[C++ Win32] Onderscheppen WM_NOTIFY verstoort List View

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Orwell
  • Registratie: December 2009
  • Laatst online: 08-09 22:11
Heb al een tijdje een probleem met mijn List View (wat een rotdingen zijn dat). Ben al een avondje bezig om subitems bij de kolommen te krijgen, maar het wil nog niet echt.

Hier m'n code voor de handigheid. Eerst de code die de kolommen maakt.
C++:
1
2
3
4
5
6
7
8
9
10
11
LVCOLUMN lvc;
            char szText[256];
            lvc.mask = LVCF_FMT|LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM;
            for (int iCol = 0; iCol < 4; iCol++) {
                lvc.iSubItem = iCol;
                lvc.pszText = szText;
                lvc.cx = 100;     // width of column in pixels
                lvc.fmt = LVCFMT_LEFT;
                LoadString(GetModuleHandle(NULL),IDS_FIRSTCOLUMN + iCol,szText,sizeof(szText)/sizeof(szText[0]));
                ListView_InsertColumn(hNote, iCol, &lvc);
            }


Dan WM_NOTIFY, wat voor het maken van lijst-subitems gebruikt wordt:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
case WM_NOTIFY: {
            switch (((LPNMHDR) lParam)->code) {
                case LVN_GETDISPINFO: {
                    NMLVDISPINFO* plvdi;
                    plvdi = (NMLVDISPINFO*) lParam;
                    switch (plvdi->item.iSubItem) {
                        case 1: {
                            plvdi->item.pszText = CijferRatioChar;
                            break;
                        }
                        case 2: {
                            plvdi->item.pszText = AantalFoutChar;
                            break;
                        }
                        case 3: {
                            plvdi->item.pszText = Cijfer;
                            break;
                        }
                    }
                    break;
                }
            }
            break;
        }


Dan de code die volgt na de 'Voeg toe'-knop:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
case IDC_PUT: {
                    char buf[32] = "Ratio: ";
                    SendMessage(hRatio,WM_GETTEXT,6,(LPARAM)CijferRatioChar);
                    strcat(buf,CijferRatioChar);
                    SendMessage(hStatus, SB_SETTEXT, 1, (LPARAM)buf);

                    char buf2[1024] = "";
                    SendMessage(hNote,WM_GETTEXT,1024,(LPARAM)buf2);
                    SendMessage(hNaam,WM_GETTEXT,32,(LPARAM)name);
                    if(strlen(name) > 0) {
                        strcat(buf2,name);
                        strcat(buf2,", ");
                    }
                    strcat(buf2,"Fout per punt: ");
                    strcat(buf2,CijferRatioChar);
                    strcat(buf2,", Aantal fout: ");
                    SendMessage(hFouten,WM_GETTEXT,6,(LPARAM)AantalFoutChar);
                    strcat(buf2,AantalFoutChar);
                    strcat(buf2,", Cijfer: ");

                    float CijferRatio = atof(CijferRatioChar);
                    float AantalFout = atof(AantalFoutChar);
                    float fCijfer = 10 - (AantalFout/CijferRatio);
                    if(fCijfer < 1.0) {
                        fCijfer = 1.0;
                    } else if(fCijfer > 10.0) {
                        fCijfer = 10.0;
                    }
                    sprintf(Cijfer,"%.1f",fCijfer);
                    strcat(buf2,Cijfer);
                    strcat(buf2,"\r\n");

                    // Lijstitems toevoegen
                    LVITEM lvI;
                    lvI.mask = LVIF_TEXT|LVIF_STATE;
                    lvI.iSubItem = 0;
                    lvI.state = 0;
                    lvI.stateMask = 0;
                    lvI.iItem = 1024;
                    lvI.pszText = name;
                // Deze volgende regel veroorzaakt de WM_NOTIFY, LVN_GETDISPINFO van hierboven
                    SendMessage(hNote,LVM_INSERTITEM,0,(LPARAM)&lvI);

                    

                    // Vullende balk
                    SendMessage(hProgress,PBM_SETPOS,65536,0);
                    break;
                }


Elke keer als ik WM_NOTIFY onderschep, of er nou alleen maar een break staat of die hele lap van daarboven, gaat meneer ListView (HWND hNote) raar doen. Selecteren werkt niet meer, kolommen willen niet meer verplaatsen, rare artefacten bij slepen items, enzovoorts.

Hier een plaatje van het geheel:
Afbeeldingslocatie: http://img88.imageshack.us/img88/2935/45029451.png

Die grote List View in het midden wordt dus zoals gezegd kreupel doordat ik WM_NOTIFY onderschep, alleen al door hem bij WndProc te vermelden met bijvoorbeeld alleen een break.

Dus, ehm, zijn er hier mensen die wel een List View met Win32 API mèt kolommen aan de gang hebben gekregen, en zouden die me kunnen uitleggen wat hier fout gaat?

[ Voor 136% gewijzigd door Orwell op 02-06-2010 20:53 ]


Acties:
  • 0 Henk 'm!

  • Reptile209
  • Registratie: Juni 2001
  • Laatst online: 00:20

Reptile209

- gers -

Klok - klepel, maar er staat me iets bij dat je (juist wel of juist niet) moet zorgen dat de WM_NOTIFY alsnog bij de control aankomt? Inderdaad, als ik dit vlotjes scan, staat daar:
For example, the list view control in report mode receives WM_NOTIFY messages from the header control and forwards them back out to its own parent, so that the list view parent can respond to header notifications. (The parent normally should just let the list view handle it, but the operation is performed in case you're one of those special cases that needs it.)
Vraag me even niet hoe, maar volgens mij zorg je nu dat je alle WM_NOTIFY messages opeet. Degenen die je niet zelf als laatste afhandelt, moet je dus weer de loop ingooien zodat je listview ze uiteindelijk krijgt.

* Reptile209 wenst u veel succes met de interpretatie van bovenstaande. :) Hopelijk helpt het je op weg.

Zo scherp als een voetbal!


Acties:
  • 0 Henk 'm!

  • Jehjoa
  • Registratie: September 2007
  • Laatst online: 27-08 09:27
Wat voor waarde returned je window procedure na het behandelen van WM_NOTIFY? Volgens de MSDN docs wordt die genegeerd, maar het zou niet de eerste keer zijn dat de documentatie fout zit.

Je kunt ook eens kijken wat er gebeurd als je return DefWindowProc(...); doet na WM_NOTIFY. Het zou namelijk goed kunnen dat Windows intern nog het één en het ander wil uitspoken met een listview control na WM_NOTIFY.

Acties:
  • 0 Henk 'm!

  • Orwell
  • Registratie: December 2009
  • Laatst online: 08-09 22:11
Reptile209 schreef op woensdag 02 juni 2010 @ 20:58:
Klok - klepel, maar er staat me iets bij dat je (juist wel of juist niet) moet zorgen dat de WM_NOTIFY alsnog bij de control aankomt? Inderdaad, als ik dit vlotjes scan, staat daar:

[...]

Vraag me even niet hoe, maar volgens mij zorg je nu dat je alle WM_NOTIFY messages opeet. Degenen die je niet zelf als laatste afhandelt, moet je dus weer de loop ingooien zodat je listview ze uiteindelijk krijgt.

* Reptile209 wenst u veel succes met de interpretatie van bovenstaande. :) Hopelijk helpt het je op weg.
Jehjoa schreef op woensdag 02 juni 2010 @ 21:02:
Wat voor waarde returned je window procedure na het behandelen van WM_NOTIFY? Volgens de MSDN docs wordt die genegeerd, maar het zou niet de eerste keer zijn dat de documentatie fout zit.

Je kunt ook eens kijken wat er gebeurd als je return DefWindowProc(...); doet na WM_NOTIFY. Het zou namelijk goed kunnen dat Windows intern nog het één en het ander wil uitspoken met een listview control na WM_NOTIFY.
Daar zeg je nou eens wat, alles wat nu dus door WM_NOTIFY gaat komt ook niet meer langs 'default', want een 'case' (WM_NOTIFY dus) klopte al. Zal wel eens de rest proberen terug te fluiten naar DefWindowProc.

Goed idee. :D

Jottem, hij doet het weer. Danku, danku!

Hoe heb ik hier eigenlijk een avond aan kunnen verknallen, zo iets duffigs over de werking van een switch. |:(

[ Voor 7% gewijzigd door Orwell op 02-06-2010 21:11 ]


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Orwell schreef op woensdag 02 juni 2010 @ 21:07:
Hoe heb ik hier eigenlijk een avond aan kunnen verknallen, zo iets duffigs over de werking van een switch. |:(
Heeft weinig van doen met de werking van een switch maar met het concept van hooken.

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij