简体   繁体   中英

Preserve painted client area between calls to WM_PAINT in win32

I am trying to paint(draw) text on the client area on a window in response to some event(not in the WM_PAINT message), so how can I preserve the state of the client area between calls to WM_PAINT ? I understand that every time there is a WM_PAINT message(or window refreshes) the window gets redrawn and everything out side WM_PAINT doesn't matter anymore. I think I will be able to communicate better with code, so here is what I have now.

HDC mdc;

int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, 
                    LPSTR lpszArgument, int nFunsterStil)
{   
    LoadBitmap(...); // for skinning the app.
    stuff.. 
}

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     case WM_PAINT:
         PAINTSTRUCT ps;

             HDC hdc = BeginPaint(hwnd, &ps);
             BITMAP bm;

             HDC dcSkin = CreateCompatibleDC(hdc);
             GetObject(hSkinBmp, sizeof(bm), &bm);
             SelectObject(dcSkin, hSkinBmp);

             BitBlt(dcSkin, 0, 0, wWidth, wHeight, mdc, 0, 0, SRCCOPY);
             BitBlt(hdc, 0, 0, wWidth, wHeight, dcSkin, 0, 0, SRCCOPY);

             DeleteDC(dcSkin);

             EndPaint(hwnd, &ps);
     break;


     case WM_LBUTTONDOWN;

          HDC hdc = GetDC( hwnd );

          mdc = CreateCompatibleDC( hdc );


          LPRECT rect;
          GetClientRect( hwnd, rect);

          SelectObject( mdc, CreateCompatibleBitmap( hdc, rect->right, rect->bottom ) );

          BitBlt( mdc,0,0,rect->right,rect->bottom,hdc,0,0,SRCCOPY );


          HFONT hfont = CreateFont( 0, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, 
                          DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, 
                          PROOF_QUALITY, DEFAULT_PITCH | FF_SWISS   , 0 );

          HFONT hOldFont = (HFONT)SelectObject( mdc, hfont );

          SetTextColor( mdc, RGB(255,0,0) );
          SetBkColor( mdc, RGB(255,255,0) );
          TextOut( mdc, 50, 150, logintext.c_str(), strlen( logintext.c_str() ) );

          SelectObject( mdc, hOldFont );
          ReleaseDC( hwnd, hdc);
          InvalidateRect( hwnd, 0, TRUE );

     break;
}

As you can see, I have to paint the client area of the window with a bmp, then when mouse button down message comes, I have to output some text on top of the skinned client area. What I am doing is saving the memory dc created in the WM_LBUTTONDOWN message and trying to paint the window dc first with the dc for skin then the dc for text(memory dc created in WM_LBUTTONDOWN ).

The skin bitmap show as it is supposed to, but the Text doesn't.

How do I achieve this ?

If I understand you correctly you want to draw things outside of WM_PAINT and have them persist. Unfortunatly that's not how windows works.

You need to be able to redraw everything in your WM_PAINT handler as the contents of the window can be destroyed at any moment and redrawn, so you have to structure your program to be able to do this. Instead of drawing anything outside of the WM_PAINT hander instead set some flags or other state telling the program what should be on the screen and then invalidate the area of the screen so that a WM_PAINT will be issued to draw that area.

One alternative which might be easier for you is to draw everything to an offscreen bitmap whenever it needs updating, and have the WM_PAINT function just draw that bitmap on the screen so it's always up to date.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM