1

我在纯 Win32 程序上的 Listview 问题当我删除项目时,然后在删除项目返回之前单击它的位置。所以 Listview 实际上不能删除任何项目

这是程序和来源:

#include <windows.h>
#include <commctrl.h>
#include <stdio.h>


#define BTN_DELETE 123

static HWND resList=NULL; 
LVITEM LvItem;
LVCOLUMN lvc;
HINSTANCE MainInstance;
HWND Test_FORM;

LRESULT CALLBACK Test_FORM_WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
   switch(msg)
   {
   case WM_CREATE:
       {
           resList= CreateWindow(WC_LISTVIEW,"", WS_CHILD | WS_BORDER |  WS_VISIBLE | LVS_REPORT,0,0,700,420,hwnd,(HMENU)666,MainInstance,NULL);
           CreateWindow("button", "Delete",WS_VISIBLE | WS_CHILD ,20, 430, 150, 30,hwnd, (HMENU) BTN_DELETE, MainInstance, NULL);


          memset(&lvc,0,sizeof(lvc));
          lvc.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM ;
          lvc.iSubItem  = 0;
          lvc.pszText   = "Items";
          lvc.cx        = 200;
          SendMessage(resList,LVM_INSERTCOLUMN,0,(LPARAM)&lvc);

          memset(&LvItem,0,sizeof(LvItem));
          LvItem.mask=LVIF_TEXT; 
          LvItem.cchTextMax = 256;
          LvItem.iItem=0; 
          LvItem.iSubItem=0;
          LvItem.pszText="Item 0";
          SendMessage(resList,LVM_INSERTITEM,0,(LPARAM)&LvItem);

       }
       break;

   case WM_COMMAND: { if(HIWORD(wParam) == BN_CLICKED) { switch(LOWORD(wParam)) { case BTN_DELETE: { ListView_DeleteAllItems(resList); } break; } } } break;
   case WM_CLOSE: {DestroyWindow(hwnd); PostQuitMessage(0); } break;

   }
   return DefWindowProc(hwnd,msg,wParam,lParam);
}

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
    MSG Msg;
    MainInstance=hInstance; 
    WNDCLASS ResClass;
    ResClass.cbClsExtra = 0;

    ResClass.cbWndExtra = 0;
    ResClass.hbrBackground = CreateSolidBrush(RGB(45,45,45));
    ResClass.hCursor = LoadCursor(NULL,IDC_ARROW);
    ResClass.hIcon = NULL;
    ResClass.lpszMenuName = NULL;
    ResClass.style = 0;
    ResClass.hInstance = NULL;

    ResClass.lpfnWndProc = Test_FORM_WndProc;
    ResClass.lpszClassName = "RES_CL";
    RegisterClass(&ResClass);
    Test_FORM = CreateWindow("RES_CL","Test",WS_DLGFRAME | WS_SYSMENU | WS_VISIBLE,CW_USEDEFAULT,CW_USEDEFAULT,700,500,NULL,0,NULL,NULL);
    Test_FORM_WndProc(Test_FORM,WM_CREATE,NULL,NULL);
    if(Test_FORM == NULL){return 1;}
    while(GetMessage(&Msg,NULL,0,0) > 0)
    {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}
4

1 回答 1

1

看起来您的主要问题是这行代码:

Test_FORM_WndProc(Test_FORM,WM_CREATE,NULL,NULL);

这根本不应该存在。当您使用 调用窗口过程时WM_CREATE,将创建第二个列表视图。只需从您的程序中删除这行代码。


其他一些评论:

你的处理方式WM_CLOSE很奇怪。您不需要处理该消息,因为默认处理程序将调用DestroyWindow. 你不应该PostQuitMessage从那里打电话。而是从WM_DESTROY. 所以,WM_CLOSE用这个替换子句:

case WM_DESTROY: 
    PostQuitMessage(0); 
    return 0;

在填充少数需要值的成员之前对结构进行零初始化可能更干净。例如:

 WNDCLASS ResClass = {0};
 ResClass.hbrBackground = CreateSolidBrush(RGB(45,45,45));
 ResClass.hCursor = LoadCursor(NULL,IDC_ARROW);
 ResClass.lpfnWndProc = Test_FORM_WndProc;
 ResClass.lpszClassName = "RES_CL";

您也在处理程序中使用这种方法WM_CREATE,但上面的语法可能比memset.

最后,我更愿意看到你的WM_CREATEWM_COMMAND处理程序使用return而不是DefWindowProc被调用。

于 2013-05-07T12:10:56.567 回答