选择一行文字

【勇芳软件工作室】汉化HomePreviousNext

本节中的示例来自简单的文字处理应用程序。它包括代码,使用户可以通过单击文本行上的任意位置来设置插入符的位置,并通过双击行中的任何位置来选择(突出显示)一行文本。

LRESULT APIENTRY MainWndProc(hwndMain,uMsg,wParam,lParam)en

HWND hwndMain;

UINT uMsg;

WPARAM wParam;

LPARAM lParam;

{

HDC hdc; /* handle of device context */

TEXTMETRIC tm; /* font size data */

int i, j; /* loop counters */

int cCR = 0; /* count of carriage returns */

char ch; /* character from input buffer */

static int nBegLine; /* beginning of selected line */

static int nCurrentLine = 0; /* currently selected line */

static int nLastLine = 0; /* last text line */

static int nCaretPosX = 0; /* x-coordinate of caret */

static int cch = 0; /* number of characters entered */

static int nCharWidth = 0; /* exact width of a character */

static char szHilite[128]; /* text string to highlight */

static DWORD dwCharX; /* average width of characters */

static DWORD dwLineHeight; /* line height */

static POINTS ptsCursor; /* coordinates of mouse cursor */

static COLORREF crPrevText; /* previous text color */

static COLORREF crPrevBk; /* previous background color */

static PTCHAR pchInputBuf; /* address of input buffer */

static BOOL fTextSelected = FALSE; /* text-selection flag */

开关(uMsg){

case WM_CREATE:

/ *获取当前字体的指标。*/

hdc = GetDC(hwndMain);

GetTextMetrics(hdc, &tm);

ReleaseDC(hwndMain, hdc);

/ *保存平均字符宽度和高度。*/

dwCharX = tm.tmAveCharWidth;

dwLineHeight = tm.tmHeight;

/ *分配缓冲区以存储键盘输入。*/

pchInputBuf = (LPSTR) GlobalAlloc(GPTR,

BUFSIZE * sizeof(TCHAR));

return 0;

case WM_CHAR:

开关(wParam){

case 0x08: /* backspace */

case 0x0A: /* linefeed */

case 0x1B: /* escape */

MessageBeep(0xFFFFFFFF);

return 0;

case 0x09: /* tab */

/ *将标签转换为四个连续空格。*/

for (i = 0; i < 4; i++)

SendMessage(hwndMain, WM_CHAR, 0x20, 0);

return 0;

case 0x0D: /* carriage return */

/*

记录回车,并定位

*在新行开始的插入符号。

*/

pchInputBuf[cch++] = 0x0D;

nCaretPosX = 0;

nCurrentLine += 1;

break;

默认值:/ *可显示字符* /

ch = (char) wParam;

HideCaret(hwndMain);

/*

*检索字符的宽度,并显示

*性格。

*/

hdc = GetDC(hwndMain);

GetCharWidth32(hdc,(UINT)wParam,(UINT)wParam,

&nCharWidth);

TextOut(hdc,nCaretPosX,

nCurrentLine * dwLineHeight, &ch, 1);

ReleaseDC(hwndMain, hdc);

/ *将字符存储在缓冲区中。*/

pchInputBuf[cch++] = ch;

/*

*计算新的水平位置

*插入符号。如果新职位超过了

*最大,插入回车和

*在开始时重新设置插入符号

*下一行。

*/

nCaretPosX += nCharWidth;

如果((DWORD)nCaretPosX > dwMaxCharX){

nCaretPosX = 0;

pchInputBuf[cch++] = 0x0D;

++nCurrentLine;

}

ShowCaret(hwndMain);

break;

}

SetCaretPos(nCaretPosX, nCurrentLine * dwLineHeight);

nLastLine = max(nLastLine, nCurrentLine);

break;

.

./ *处理其他消息。*/

.

case WM_LBUTTONDOWN:

/*

*如果当前高亮显示一行文本,请重新绘制

*文字删除突出显示。

*/

if(fTextSelected){

hdc = GetDC(hwndMain);

SetTextColor(hdc, crPrevText);

SetBkColor(hdc, crPrevBk);

TextOut(hdc,0,nCurrentLine * dwLineHeight,

szHilite, lstrlen(szHilite));

ReleaseDC(hwndMain, hdc);

ShowCaret(hwndMain);

fTextSelected = FALSE;

}

/ *保存当前鼠标光标坐标。*/

ptsCursor = MAKEPOINTS(lParam);

/*

*确定光标所在的行,并保存

*行号。不允许行数更大

*比最后一行的文字数。该

*行数乘以平均高度

*的当前字体。结果用于设置

*插入符号的y坐标。

*/

nCurrentLine = min((int)(ptsCursor.y / dwLineHeight),

nLastLine);

/*

*解析文本输入缓冲区以查找第一个

*所选文字行中的字符。每

*线以回车方式结束,所以有可能

*计数回车查找所选的

*行。

*/

cCR = 0;

nBegLine = 0;

if (nCurrentLine != 0) {

for (i = 0; (i < cch) &&

(cCR < nCurrentLine); i++) {

if (pchInputBuf[i] == 0x0D)

++cCR;

}

nBegLine = i;

}

/*

*从所选行的开头开始,

*测量每个字符的宽度,求和

*宽度与每个字符测量。停止时

* sum大于光标的x坐标。

*总和用于设置插入符号的x坐标。

*/

hdc = GetDC(hwndMain);

nCaretPosX = 0;

for (i = nBegLine;

(pchInputBuf[i] != 0x0D) && (i < cch); i++) {

ch = pchInputBuf[i];

GetCharWidth32(hdc, (int) ch, (int) ch, &nCharWidth);

if((nCaretPosX + nCharWidth)> ptsCursor.x)

break;

其他

nCaretPosX += nCharWidth;

}

ReleaseDC(hwndMain, hdc);

/ *将插入符号设置为用户选择的位置。*/

SetCaretPos(nCaretPosX, nCurrentLine * dwLineHeight);

break;

case WM_LBUTTONDBLCLK:

/ *将选定的文本行复制到缓冲区。*/

for (i = nBegLine, j = 0; (pchInputBuf[i] != 0x0D) &&

(i < cch); i++)

szHilite[j++] = pchInputBuf[i];

szHilite[j] = '\0';

/*

*隐藏插入符号,反转背景和前景

*颜色,然后重画所选行。

*/

HideCaret(hwndMain);

hdc = GetDC(hwndMain);

crPrevText = SetTextColor(hdc, RGB(255, 255, 255));

crPrevBk = SetBkColor(hdc, RGB(0, 0, 0));

TextOut(hdc,0,nCurrentLine * dwLineHeight,szHilite,

lstrlen(szHilite));

SetTextColor(hdc, crPrevText);

SetBkColor(hdc, crPrevBk);

ReleaseDC(hwndMain, hdc);

fTextSelected = TRUE;

break;

.

./ *处理其他消息。*/

.

默认:

return DefWindowProc(hwndMain, uMsg, wParam, lParam);

}

return NULL;

}