WM_PAINT消息,BeginPaint循环

时间:2018-08-03 11:12:27

标签: winapi gdi wm-paint

我不明白为什么我在BeginPaint函数上出现了循环。我已经阅读了有关这种循环的文章,但几乎所有文章都建议:“不要忘记在WM_PAINT消息上使用BeginPaint函数,因为否则就需要后续的WM_PAINT消息”。这不是我的情况。你可以给我一些建议吗?

这是我的窗口类(“ CWindow”):

class CWindow {
public:

   CWindow();
   virtual ~CWindow();
   bool RegisterClass(HINSTANCE hInstance);
   bool CreateWnd(HINSTANCE hInstance);
   bool Show(int nShow);
private:

    HWND handleWindow;
    ATOM atom;
    bool isRegistered;
    bool isCreated;
    static LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
    void OnPaint();
    void OnDestroy();
};

WndProc函数。

LRESULT CALLBACK CWindow::WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{  
    CWindow* windowPtr = reinterpret_cast<CWindow*> ( GetWindowLongPtr( hWnd, GWLP_USERDATA ) );
    PAINTSTRUCT ps;
    HDC hdc;
    switch( msg ) {  
        case WM_PAINT:
            // There is a loop right here!
            hdc = BeginPaint( windowPtr->handleWindow,  &ps );
            // The code below doesn't executed!
            RECT rect;
            (void)GetClientRect(windowPtr->handleWindow, &rect);

            (void)DrawText(hdc, TEXT("Hello, Windows 98!"), -1, &rect,
            DT_SINGLELINE | DT_CENTER | DT_VCENTER);

            EndPaint( windowPtr->handleWindow, &ps );
            break;
        case WM_DESTROY:
            windowPtr->OnDestroy();
            break;
        default:
            return DefWindowProc( hWnd, msg, wParam, lParam );
    }
    return 0;
}

RegisterClass

bool CWindow::RegisterClass(HINSTANCE hInstance)
{
    const TCHAR app_name[] = TEXT("HelloWin");
    WNDCLASSEX  windowClass;

    ZeroMemory( &windowClass, sizeof(windowClass) );
    windowClass.cbSize = sizeof(windowClass);
    windowClass.style = CS_HREDRAW | CS_VREDRAW;
    windowClass.lpfnWndProc = WindowProc;
    windowClass.cbClsExtra = 0;
    windowClass.cbWndExtra = 0;
    windowClass.hInstance = hInstance;
    windowClass.hIcon = 0;
    windowClass.hIcon = 0;
    windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    windowClass.hbrBackground = 0;
    windowClass.lpszMenuName = NULL;
    windowClass.lpszClassName = app_name;
    windowClass.hIconSm = NULL;

    atom = RegisterClassEx( &windowClass );
    DWORD errorCode = GetLastError();
    if( errorCode ) {
        isRegistered = 0;
        std::wcout << L"ErrorCode: " << errorCode << std::endl;
    } else {
        isRegistered = 1;
    }
    return isRegistered;
}

CreateWindow

bool CWindow::CreateWnd(HINSTANCE hInstance)
{
    handleWindow = CreateWindow((PCTSTR)atom,               // window class name or atom
                         TEXT("The Hello Program"),  // window caption
                         WS_OVERLAPPEDWINDOW,        // window style
                         CW_USEDEFAULT,              // initial x position
                         CW_USEDEFAULT,              // initial y position
                         CW_USEDEFAULT,              // initial x size
                         CW_USEDEFAULT,              // initial y size
                         NULL,                       // parent window handle
                         NULL,                       // window menu handle
                         hInstance,                  // program instance handle
                         NULL);                      // creation parameters 
    DWORD errorCode = GetLastError();
    if( !handleWindow ) {
        isCreated = 0;
    } else { 
        isCreated = 1;
    }
    return isCreated;
}

显示

bool CWindow::Show(int nShow)
{
    if( isCreated ) {
        ShowWindow( handleWindow, nShow );
        return UpdateWindow( handleWindow );
    } else {
        return 0;
    }
}

WinMain

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevINstance, LPSTR lpCmdLine, int nShow )
{
    CWindow window;
    window.RegisterClass( hInstance );
    window.CreateWnd( hInstance );
    window.Show( nShow );
    int response = 0;
    MSG msg;
    while( GetMessage( &msg, 0, 0, 0 ) ) {
        TranslateMessage( &msg );
        DispatchMessage( &msg );
    }
        return 0;
    }

1 个答案:

答案 0 :(得分:1)

由于您从不致电.container { padding: 0 'min_margin_ammount' 0 0; } .your_div_with_items { margin: 0 33% 0 0; }

numpy.hstack

返回一个 list_of_arrays = [ array_1, ..., array_n] #all these arrays have same shape[0] big_array = np.hstack( list_of_arrays) ,您随后尝试取消引用:

SetWindowLongPtr

这将触发访问冲突异常,导致CWindow* windowPtr = reinterpret_cast<CWindow*>( GetWindowLongPtr( hWnd, GWLP_USERDATA ) ); 调用甚至永远不会执行,从而使无效区域保持原样。结果,系统不断生成nullptr消息。这与完全不调用BeginPaint( windowPtr->handleWindow, &ps ) 相同。 1

要解决此问题,您将必须通过调用BeginPaint将窗口句柄附加到窗口实例,或者仅使用传递到WM_PAINT中的BeginPaint参数。 / p>


1 请注意,在某些情况下,系统会静默处理您的WindowProc在64位版本的Windows上未处理的异常。