2016-11-26 49 views
2

我正在創建一個所有者繪製的列表框控件,我設法創建並填充沒有錯誤。MSDN(擁有者繪製)滾動後列表框控件凍結

這裏是我的問題: 當我把它的滾動,列表框和它的父窗口滾動了幾秒鐘後,變得沒有反應(與PgDown鍵)

需要注意的是:

  • 其中有很多物品(超過4k)

  • 消息仍在處理中,我可以監控他們在控制檯上,他們正在發送和接收。 唯一的區別是,WM_DRAWITEM不再發送...

  • ListBox的項目是通過LB_ADDSTRING

我試了一下說:

  • 使用的PeekMessage函數,而不是的GetMessage

- >列表填充後程序崩潰

  • 重繪窗戶發生後的問題(通過WM_LDOUBLECLICK事件例如)

- >沒有effets

代碼片段:

  • 窗口過程

    LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 
        { 
         HBRUSH Brush; 
         HBRUSH BLANK_BRUSH; 
         HBRUSH BLUE_BRUSH; 
         Brush = CreateSolidBrush(RGB(163, 255, 249)); 
         BLANK_BRUSH = CreateSolidBrush(RGB(255,255, 255)); 
         BLUE_BRUSH = CreateSolidBrush(RGB(0,0, 255)); 
         int tabs[13]={140,256,261,287,318,353,422,460,500,530,550,570,610}; 
         switch(msg) 
         { 
          HDC hdc ; 
          PAINTSTRUCT ps ; 
          PMEASUREITEMSTRUCT pmis; 
          LPDRAWITEMSTRUCT Item; 
          RECT rect ; 
          rect.top=-50; 
          rect.bottom=0; 
          RECT rect2 ; 
          rect.top=10; 
          case WM_MEASUREITEM: 
           pmis = (PMEASUREITEMSTRUCT) lParam; 
           pmis->itemHeight = 17; 
           return TRUE; 
          break; 
          case WM_DRAWITEM: 
            Item = (LPDRAWITEMSTRUCT)lParam; 
            if (Item->itemState & ODS_FOCUS) 
            { 
             SetTextColor(Item->hDC, RGB(255,255,255)); 
             SetBkColor(Item->hDC, RGB(0, 0, 255)); 
             FillRect(Item->hDC, &Item->rcItem, (HBRUSH)BLUE_BRUSH); 
            } 
            else 
            { 
             SetTextColor(Item->hDC, RGB(0,0,0)); 
             SetBkColor(Item->hDC, RGB(255, 255, 255)); 
             FillRect(Item->hDC, &Item->rcItem, (HBRUSH)BLANK_BRUSH); 
            } 
            int len = SendMessage(Item->hwndItem , LB_GETTEXTLEN, (WPARAM)Item->itemID, 0); 
             if (len > 0) 
             { 
              LPCTSTR lpBuff = malloc((len+1)*sizeof(TCHAR)); 
              len = SendMessage(Item->hwndItem , LB_GETTEXT, (WPARAM)Item->itemID, (LPARAM)lpBuff); 
              if (len > 0) { 
               TabbedTextOut(Item->hDC,Item->rcItem.left, Item->rcItem.top,(LPARAM)lpBuff,len,13,&tabs,140); 
              } 
             } 
            return TRUE; 
          break; 
          case WM_CLOSE: 
           DestroyWindow(hwnd); 
          break; 
          case WM_PAINT: 
           hdc = BeginPaint (hwnd, &ps) ; 
           GetClientRect(hwnd, &rect); 
           SetBkColor(hdc, RGB(230,50,2)); 
           SetBkMode(hdc,TRANSPARENT); 
           FillRect(hdc,&ps.rcPaint,Brush); 
           DrawText(hdc, TEXT("Liste des messages décodés: "), -1, &rect, DT_CENTER); 
           DrawText(hdc, TEXT("Numéro d'engin (4xxxy): "), -1, &rect, DT_LEFT); 
           EndPaint (hwnd, &ps); 
           return 0 ; 
          case WM_DESTROY: 
           PostQuitMessage(0); 
          break; 
          case WM_ERASEBKGND: 
           return TRUE; 
          break; 
          default: 
           return DefWindowProc(hwnd, msg, wParam, lParam); 
         } 
         return 0; 
    }
  • 消息循環


    BOOL bRet; 
      while (1) 
      { 
       bRet = GetMessage(&Msg, NULL, 0, 0); 
       if (bRet > 0) 
       { 
        TranslateMessage(&Msg); 
        DispatchMessage(&Msg); 
       } 
       else if (bRet == 0){ 
        break; 
       } 
       else 
       { 
        printf("error\n"); 
        return -1; 
       } 
      } 
      return Msg.wParam; 
  • 窗口創建

    WNDCLASSEX WC;

    wc.cbSize  = sizeof(WNDCLASSEX); 
    wc.style   = 0; 
    wc.lpfnWndProc = WndProc; 
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = 0; 
    wc.hInstance  = hInstance; 
    wc.hIcon   = LoadIcon(NULL, IDI_APPLICATION); 
    wc.hCursor  = LoadCursor(NULL, IDC_ARROW); 
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 
    wc.lpszMenuName = NULL; 
    wc.lpszClassName = g_szClassName; 
    wc.hIconSm  = LoadIcon(NULL, IDI_APPLICATION); 
    
    RegisterClassEx(&wc); 
    
    hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,g_szClassName,"List of messages",WS_OVERLAPPEDWINDOW,0, 0, 1500, 1000,NULL, NULL, hInstance, NULL); 
    ShowWindow(hwnd, nCmdShow); 
    UpdateWindow(hwnd); 
    
    if(hwnd == NULL) 
    { 
        return 0; 
    } 
        hwnd2 = CreateWindowEx(0,"LISTBOX" ,"Data",WS_CHILD |WS_HSCROLL |WS_VSCROLL |WS_BORDER|WS_THICKFRAME | LBS_USETABSTOPS | LBS_OWNERDRAWFIXED | LBS_NOTIFY | LBS_HASSTRINGS,15,70,1450,450,hwnd,(HMENU) NULL,hInstance,NULL); 
    

它看起來像有一個計時器的地方,如果鍵盤觸摸停留時間過長了,它在某種程度上打亂了一切......

有人曾經遇到過這樣的問題之前,或能幫助我理解發生了什麼?

+0

聲明你的畫筆「靜態」並刪除它們以響應'WM_CLOSE',這應該是一個快速修復你的問題... – AlwaysLearningNewStuff

回答

3

您的代碼中存在嚴重的GDI資源泄漏。

在您的WndProc函數的頂部,您正在創建三個畫筆,並且您從不刪除它們。這些畫筆每次創建您的窗口處理消息。

您應該只在實際需要繪畫時創建畫筆,並在完成繪畫時撥打DeleteObject以釋放它們。

+0

謝謝喬納森, 我會嘗試儘快。 – UGC