Toon posts:

[C#+Win API] Tristate checkboxes in TreeView

Pagina: 1
Acties:

Verwijderd

Topicstarter
Okay, voor de .NET gurus:

De standaard TreeView in .NET heeft alleen checkboxes met twee states, maar ik wil er drie... Dit is dus mogelijk door een andere state imagelist te gebruiken en vervolgens kun je een willekeurig aantal states gebruiken.

Het ophalen en zetten van die states in .NET/C# kan door zelf de TVITEM struct te definieren en die mbv SendMessage naar je tree control te posten... Met wat zoeken op internet en het nodige knip en plak werk krijg je dan uiteindelijk deze code (Sorry, code is nog een beetje een zooitje)... Belangrijkste method die voor problemen zorgt is dus SetStateImage: (C# code dus en geen java, maar [ code=c#] doet geen syntax hilighting)

Java:
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
protected unsafe void SetStateImage(TreeNode tn, int ImageIndex)
        {
            // uses the TVM_SETITEM message to set the state
            // of a given item. Uses the TVITEM structure
            // defining the required structure

            TVITEM tvi = new TVITEM();

            // tvi.mask: include TVIF_HANDLE and TVIF_STATE
            tvi.mask = 8 | 16;
            // tvi.state - which index in the image list to use
            tvi.state = (uint)ImageIndex;
            tvi.state = tvi.state << 12; // shift 12 to put info in bits 12 to 15
            // setting stateMask - required to isolate state above
            tvi.stateMask = 61440; // TVIS_STATEIMAGEMASK
            // defining the item we want to set the state
            tvi.hItem = tn.Handle;
            // init the rest to zero
            tvi.pszText = (IntPtr)0;
            tvi.cchTextMax = 0;
            tvi.iImage = 0;
            tvi.iSelectedImage = 0;
            tvi.cChildren = 0;
            tvi.lParam = (IntPtr)0;
            // calling the TVM_SETITEM message
            // TVM_SETITEM = 4365

            SendMessage(this.Handle,(UInt32)TVM_SETITEM,(UInt32)0,new IntPtr(&tvi).ToInt32());
        }


Lijkt allemaal prima te werken, ik helemaal blij :), tot ik ontdek dat de checkboxes/state images na een tijdje spontaan verdwijnen :'(... De app starten en een tijdje de treeview control resizen zodat ie flink vaak moet worden ge-update is genoeg om het probleem te reproduceren... :|

Voor de duidelijkheid; tijdens het resizen word er geen code van mij uitgevoerd, daar kan dus geen fout in zitten... Na het lezen van deze thread op google heb ik het vermoeden dat het probleem misschien bij de garbage collector/memory management ligt (juist ook omdat de verdwijnen op een random moment gebeurd.), maar wat dan precies het probleem is is mij nog niet helemaal duidelijk... (het enige probleem zou kunnen zijn dat de TVITEM struct gedestruct/verplaatst wordt terwijl de TreeView er nog steeds een pointer naar heeft, maar dit is volgens mij niet zo aangezien in C++ je hier ook zonder problemen een pointer naar een object op de stack mag meegeven)

Dus wie weet wat hier fout is, of wie heeft zin om net als ik Visual Studio aan te slingeren om uit te zoeken wat er hier niet goed gaat (Als beloning krijg je een correct werkende TreeView met tri-state checkboxes! :+)

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:57
Als je een stuk geheugen (object) hebt, waar nog altijd naar gerefereerd is, zal de Garbage Collector dat object niet gaan vernietigen.

https://fgheysels.github.io/


Verwijderd

Topicstarter
whoami schreef op 19 June 2003 @ 13:17:
Als je een stuk geheugen (object) hebt, waar nog altijd naar gerefereerd is, zal de Garbage Collector dat object niet gaan vernietigen.
Klopt, maar de C# gc weet niet of achter een api (=C++ oid) er nog een pointer wordt bewaard... Verder is de gc vrij objecten te verplaatsen in het geheugen.. Binnen de C# app zullen alle pointers dan netjes aangepast worden, maar ook hier zal unmanaged code (achter de API) niet echt blij zijn...

(De SendMessage method zit namelijk niet in een .NET library, maar in een gewone C++ dll, user32.dll oid)

[ Voor 12% gewijzigd door Verwijderd op 19-06-2003 13:25 ]