2010-12-23 77 views
0

我最近有我的主窗口使用WM_PAINT写文本,但现在我意识到这可能不是最好的消息,所以我尝试了另一个版本;win32:TextOut not displayed

主窗口包含一个菜单,在菜单项中ID_FILE_PID消息被发送并且它构建4个新窗口以及在主窗口(paintEditSigns函数)中显示文本。 4个窗口工作正常,但文本dosn't工作根本,除非我在main()函数中执行,如图所示...究竟是什么? O_O

顺便说一句:我仍然不知道为什么当我发布时,StackOverflow上的代码显示看起来很奇怪,为什么?

switch(message) 
    { 
    case WM_COMMAND: 
    switch (LOWORD(wParam)) 
     { 
      case ID_FILE_PID: 
      { 
       HWND hWndButton;  
       HWND hWndEdit; 
       HWND hWndEdit2; 
       HWND hWndDisplay; 

       // drawing the text in mainwindow 
       trigger=true; 

       // adding new windows in the mainwindow 
       hWndButton = CreateWindowEx(0,TEXT("BUTTON"),"Modify",WS_CHILD | WS_VISIBLE | 
       BS_DEFPUSHBUTTON, 170,56,80,30,hWnd,(HMENU)ID_BUTTON,hThisInstance,NULL); 
       hWndEdit = CreateWindowEx(0,RICHEDIT_CLASS,TEXT(""),WS_CHILD | WS_VISIBLE | WS_BORDER, 
       120,30,80,25,hWnd,(HMENU)ID_EDIT,hThisInstance,NULL); 
       hWndEdit2 = CreateWindowEx(0,RICHEDIT_CLASS,TEXT(""),WS_CHILD | WS_VISIBLE | WS_BORDER, 
       220,30,80,25,hWnd,(HMENU)ID_EDIT2,hThisInstance,NULL); 
       hWndDisplay = CreateWindowEx(0,TEXT("STATIC"),NULL,WS_CHILD | WS_VISIBLE | WS_BORDER, 
       0,100,450,140,hWnd,(HMENU)ID_DISPLAY,hThisInstance,NULL); 


          UpdateWindow(hWnd); 

       break; 
      } 

..... 

case WM_PAINT: 
    { 
     if (trigger) { 
      paintEditSigns() 
     } 
     break; 

    } 

// 
// Main function 
// 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
       LPSTR lpCmdLine, int nCmdShow) 
{ 
    HWND hWnd; 
    WNDCLASSEX wc; 
    ZeroMemory(&wc, sizeof(WNDCLASSEX)); 
    hThisInstance = hInstance; 
    LoadLibrary("Riched20.dll"); 

    wc.cbSize = sizeof(WNDCLASSEX); 
    wc.style = CS_HREDRAW | CS_VREDRAW; 
    wc.lpfnWndProc = WindowProc; 
    wc.hInstance = hInstance; 
    wc.lpszMenuName = MAKEINTRESOURCE(IDR_MYMENU); 
    if(!(wc.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_MYICON)))) { 
     HRESULT res = GetLastError(); 

    } 
    wc.hCursor = LoadCursor(NULL, IDC_ARROW); 
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW; 
    wc.lpszClassName = TEXT("testcpp"); 
    RegisterClassEx(&wc); 

    hWnd = CreateWindowEx(NULL, 
          wc.lpszClassName, 
          TEXT("test"), 
          WS_OVERLAPPEDWINDOW, 
          300, 
          200, 
          450, 
          300, 
          NULL, 
          NULL, 
          hInstance, 
          NULL); 
    ShowWindow(hWnd,nCmdShow); 
     //paintEditSigns() -- here it works, but not when in the message part 

    MSG msg; 
    while (GetMessage(&msg, NULL,0,0)) { 
     TranslateMessage(&msg); 
     DispatchMessage(&msg); 

    } 


    return msg.wParam; 
} 



void paintEditSigns() { 
    HFONT hf = createFont(); 
    PAINTSTRUCT ps; 
    HWND hWnd = FindWindow(TEXT("testcpp"),TEXT("test")); 
    HBRUSH hbruzh = CreateSolidBrush(RGB(0,0,0)); 
    HDC hdz = BeginPaint(hWnd,&ps); 
    string s = "Memory Address"; 

    SelectBrush(hdz,hbruzh); 
    SelectFont(hdz,hf); 
    TextOut(hdz,0,100,s.c_str(),s.length()); 
    EndPaint(hWnd,&ps); 

    DeleteObject(hbruzh); 

} 

HFONT createFont() { 
    HDC hdc; 
    long lfHeight; 

    hdc = GetDC(NULL); 
    lfHeight = -MulDiv(12, GetDeviceCaps(hdc, LOGPIXELSY), 72); 
    ReleaseDC(NULL, hdc); 

    HFONT hf = CreateFont(lfHeight, 0, 0, 0, 0, TRUE, 0, 0, 0, 0, 0, 0, 0, "MS Sans Serif"); 
    return hf; 

} 
+0

要修改格式,您应该选择您的代码,然后单击编辑器工具栏中的“{}”按钮,这会将所有代码缩进4个空格,然后将其作为代码格式化。 – 2010-12-23 14:53:50

+0

关于你的代码的几条评论:1)你不应该在设备上下文中选择一个GDI对象`DeleteObject`。通常的做法是保存旧的对象句柄,然后在“DeleteObject”之前重新选择它。 2)`LoadLibrary`返回一个ref-counting句柄。适当时您应该释放该句柄。 3)你不需要使用`UpdateWindow`。 GDI和winapi绘画需要很多习惯,所以我认为每个人在某个时候都会遇到这样的问题。请仔细阅读API的MSDN文档,不要忽略混淆的部分;试着去了解他们。 – tenfour 2010-12-23 15:00:24

回答

1

您可以使用BeginPaint/EndPaint响应WM_PAINT。并WM_PAINT是这样做的绘图适当的地方。

当窗口的一部分“失效”时,Windows调用WM_PAINT。例如,如果您恢复窗口,或者窗口的一部分在将窗口移开或调整窗口大小之后变为可见。

当您需要手动更新显示时,通过调用InvalidateRect(这告诉Windows需要重绘的窗口区域),使需要重绘的区域“无效”。

通常是使整个窗口无效,而不是计算要绘制的区域的实际像素完美边界。