WINAPI防止我的窗口闪烁?

时间:2016-02-21 13:34:04

标签: c++ winapi draw

我的C ++ WINAPI代码出现问题,正如标题所示,我的窗口,当我重绘它时,它会闪烁。

这是我的代码:

  #include <windows.h>
  #include <thread>
  #include <chrono>
  #include <mutex>

  #define TM_REDRAW 0x21

  static HICON hIconLarge, hIconSmall;
  static int i=55+75;

  void CALLBACK disegnaIcona(LPCSTR, HDC, DWORD, DWORD);
  void CALLBACK drawBitmap(LPCSTR, HDC, DWORD, DWORD);


  void WINAPI CALLBACK sfondo(HDC hdc) {
    drawBitmap(TEXT("Images\\Layout\\background.bmp"), hdc, 0, 0);
    drawBitmap(TEXT("Images\\Layout\\scacchiera.bmp"), hdc, 350, 10);
    }

    static void WINAPI CALLBACK piazzaPezzi(HDC hdc, HWND hwnd) {
    //disegna Ic0na = draw Icon
    disegnaIcona(TEXT("Pezzi\\Torre.ico"), hdc, 399, 55);
    disegnaIcona(TEXT("Pezzi\\Cavallo.ico"), hdc, 399+73+1, 55);
    disegnaIcona(TEXT("Pezzi\\Torre.ico"), hdc, 400+7*73+4, 55);
    disegnaIcona(TEXT("Pezzi\\TorreNero.ico"), hdc, 400+7*73+7, 55+7*75-11);
    disegnaIcona(TEXT("Pezzi\\TorreNero.ico"), hdc, 402, 55+7*75-11);
    disegnaIcona(TEXT("Pezzi\\CavalloR.ico"), hdc, 399+6*73+5, 53+1);
    disegnaIcona(TEXT("Pezzi\\CavalloRNero.ico"), hdc, 399+6*73+5, 55+7*75-7);
    disegnaIcona(TEXT("Pezzi\\CavalloNero.ico"), hdc, 399+73+2, 55+7*75-10);
    disegnaIcona(TEXT("Pezzi\\Alfiere.ico"), hdc, 399+2*73+1, 55+1);
    disegnaIcona(TEXT("Pezzi\\Alfiere.ico"), hdc, 399+5*73+5, 55+1);
    disegnaIcona(TEXT("Pezzi\\AlfiereNero.ico"), hdc, 399+2*73+2, 55+7*75-10);
    disegnaIcona(TEXT("Pezzi\\AlfiereNero.ico"), hdc, 399+5*73+5, 55+7*75-10);
    disegnaIcona(TEXT("Pezzi\\Re.ico"), hdc, 399+3*73+1, 52+1);
    disegnaIcona(TEXT("Pezzi\\ReNero.ico"), hdc, 399+3*73+2, 55+7*75-10);
    disegnaIcona(TEXT("Pezzi\\Regina.ico"), hdc, 399+4*73+1, 52+1);
    disegnaIcona(TEXT("Pezzi\\ReginaNero.ico"), hdc, 402+4*73+2, 55+7*75-10);
    disegnaIcona(TEXT("Pezzi\\Pedone.ico"), hdc, 400, 53+75);
    disegnaIcona(TEXT("Pezzi\\Pedone.ico"), hdc, 400+2*73, 53+75);
    disegnaIcona(TEXT("Pezzi\\Pedone.ico"), hdc, 400+4*73+2, i);
    disegnaIcona(TEXT("Pezzi\\Pedone.ico"), hdc, 400+6*73+2, i);
    disegnaIcona(TEXT("Pezzi\\Pedone.ico"), hdc, 400+1*73, 53+75);
    disegnaIcona(TEXT("Pezzi\\Pedone.ico"), hdc, 400+3*73, 53+75);
    disegnaIcona(TEXT("Pezzi\\Pedone.ico"), hdc, 400+5*73, 53+75);
    disegnaIcona(TEXT("Pezzi\\Pedone.ico"), hdc, 400+7*73+6, 53+75);
    disegnaIcona(TEXT("Pezzi\\PedoneNero.ico"), hdc, 400+6*73+7, 53+6*75-6);
    disegnaIcona(TEXT("Pezzi\\PedoneNero.ico"), hdc, 400+4*73+7, 53+6*75-6);
    disegnaIcona(TEXT("Pezzi\\PedoneNero.ico"), hdc, 400+2*73+7, 53+6*75-6);
    disegnaIcona(TEXT("Pezzi\\PedoneNero.ico"), hdc, 400, 53+6*75-6);
    disegnaIcona(TEXT("Pezzi\\PedoneNero.ico"), hdc, 400+73, 53+6*75-6);
    disegnaIcona(TEXT("Pezzi\\PedoneNero.ico"), hdc, 400+3*73+7, 53+6*75-6);
    disegnaIcona(TEXT("Pezzi\\PedoneNero.ico"), hdc, 400+5*73+7, 53+6*75-6);
    disegnaIcona(TEXT("Pezzi\\PedoneNero.ico"), hdc, 400+7*73+7, 53+6*75-6);
    i++;
     }

   void CALLBACK drawBitmap(LPCSTR path, HDC hdc, DWORD xpos, DWORD ypos) {
    HBITMAP         bit;
    BITMAP          bitmap;
    HDC             hdcMem;
    HGDIOBJ         oldBitmap;
    bit      =      (HBITMAP)LoadImage (0, path, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);


    hdcMem = CreateCompatibleDC(hdc);
    oldBitmap = SelectObject(hdcMem, bit);

    GetObject(bit, sizeof(bitmap), &bitmap);
    BitBlt(hdc, xpos, ypos, bitmap.bmWidth, bitmap.bmHeight, hdcMem, 0, 0, SRCCOPY);

    SelectObject(hdcMem, oldBitmap);
    DeleteDC(hdcMem);
   }

  void CALLBACK disegnaIcona(LPCSTR path, HDC hdc, DWORD xpos, DWORD ypos) {
HICON hIconLarge = (HICON) LoadImage( NULL, path, IMAGE_ICON, 72, 78, LR_LOADFROMFILE| LR_SHARED| LR_LOADTRANSPARENT| LR_DEFAULTSIZE);

DrawIconEx( hdc, xpos, ypos ,hIconLarge, 72, 78, 0, NULL, DI_NORMAL);
DestroyIcon(hIconLarge);    
 }

   LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {


switch(Message) {
    case WM_CREATE:
        SetTimer( hwnd, TM_REDRAW, 100, NULL );
    break;

    case WM_ERASEBKGND:
        return true;
    break;

    case WM_PAINT:

    PAINTSTRUCT     ps;
    HDC             hdc;
    hdc = BeginPaint(hwnd, &ps);

    sfondo(hdc);    // Sfondo = background
    piazzaPezzi(hdc, hwnd); // piazzaPezzi = draw pieces


    EndPaint(hwnd, &ps);
    break;

    case WM_TIMER:
        RedrawWindow(hwnd, 0, 0, RDW_INVALIDATE | RDW_INTERNALPAINT);
        break;

    case WM_DESTROY: {
        PostQuitMessage(0);
        break;
    }


    default:
        return DefWindowProc(hwnd, Message, wParam, lParam);
}
return 0;
}


 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, char* lpCmdLine, int nCmdShow) {
WNDCLASSEX wc;
HWND hwnd;
MSG msg;

memset(&wc,0,sizeof(wc));
wc.cbSize        = sizeof(WNDCLASSEX);
wc.lpfnWndProc   = WndProc;
wc.hInstance     = hInstance;
wc.hCursor       = LoadCursor(NULL, IDC_ARROW);


wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszClassName = "WindowClass";
wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);
wc.style        =  CS_SAVEBITS;

if(!RegisterClassEx(&wc)) {
    MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
    return 0;
}

hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","Caption",WS_VISIBLE|WS_OVERLAPPEDWINDOW | WS_MAXIMIZE,
    CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL,NULL,hInstance,NULL);

if(hwnd == NULL) {
    MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
    return 0;
}

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

return msg.wParam;
 }

我想要做的不是重绘整个窗口,而只是重绘整个窗口的一部分,即发生变化的部分。可能吗?如果有,怎么样?否则我怎么能避免闪烁?

谢谢大家。

0 个答案:

没有答案