Pergunta

My problem with Listview on pure Win32 program When i delete the item then click at it location before delete the item return. So the Listview Can't delete any items actually

This the program and source :

#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;
}
Foi útil?

Solução

It looks like your main problem is this line of code:

Test_FORM_WndProc(Test_FORM,WM_CREATE,NULL,NULL);

This should simply not be there. When you call the window proc with WM_CREATE, a second list view is created. Simply remove this line of code from your program.


Some other comments:

Your handling of WM_CLOSE is odd. You don't need to handle that message since the default handler will call DestroyWindow. And you should not call PostQuitMessage from there. Instead call it from WM_DESTROY. So, replace the WM_CLOSE clause with this:

case WM_DESTROY: 
    PostQuitMessage(0); 
    return 0;

It's probably cleaner to zero-initialize a struct before populating the handful of members that need values. For example:

 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";

You use this approach in the WM_CREATE handler too, but the syntax above is perhaps a little more idiomatic than memset.

Finally, I'd prefer to see your WM_CREATE and WM_COMMAND handlers use return rather than letting DefWindowProc be called.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top