-1
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{

HDC             hdc;
PAINTSTRUCT     ps;
TCHAR           szBuffer[1];



switch (message)
{
case WM_CHAR:
    szBuffer[1] = (TCHAR) wParam;
    cout << wParam << " " << szBuffer[1] << " ";

    break;

case WM_PAINT:
    InvalidateRect(hwnd, NULL, TRUE);
    hdc = BeginPaint(hwnd, &ps);
    SelectObject(hdc,GetStockObject(SYSTEM_FIXED_FONT));
    TextOut(hdc, 1, 1, szBuffer, 1);
    EndPaint(hwnd, &ps);
    return 0;

大家好,我正在尝试运行上面的代码,并在我的窗口上一次打印一个字母。但是,我似乎无法使用 TextOut 功能让字符出现在窗口上,但能够在终端窗口中显示字符。我是 WinApi 的新手,我迷路了!

提前致谢!

4

1 回答 1

3

szBuffer是本地WndProc()变量,默认情况下,C 中的局部变量具有自动存储:每次WndProc()调用你时,都会创建一个新变量szBuffer,所以当你WM_PAINT到达时,输入的任何内容WM_CHAR都丢失了。您将需要存储在szBuffer其他地方,例如 outside WndProc(),或将其声明为static,这将保留缓冲区(但请注意静态存储对于递归来说是不安全的)。

同样在 C 中,数组的第一个元素的索引为 0,而不是 1;这条线szBuffer[1] = (TCHAR) wParam;需要szBuffer[0] = (TCHAR) wParam;做你想做的事。


由于我假设您是 C 的新手,因此请参阅 Jonathan Potter 的评论,关于在您的字符串中有一个值为 0 的额外字符(不是数字零的字符代码,而是数值 0 或'\0'or L'\0')。虽然TextOut()和其他 GDI 文本绘图函数不使用这些以null 结尾的字符串但 C 中的所有其他内容都可以。小心。


乔·威尔科克森的评论也是正确的。InvalidateRect()将给定的矩形排队为需要重绘。在你的处理程序中使用它WM_PAINT会导致你总是WM_PAINT一遍又一遍地收到消息,随着你的程序变得越来越大,这将对性能产生负面影响。

于 2014-11-18T22:57:08.897 回答