News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Treeview with side panel

Started by bozo, April 03, 2010, 08:31:20 PM

Previous topic - Next topic

bozo

So i've searched in many places for some code or explanation how it's done but most code is for .NET or MFC and i just wanted Win32 API used..
If you see from the picture attached from uTorrent(closed source), there's a treeview on the left hand side and a "panel" on the right side.
When you select one of the tree nodes, a different "page" is displayed on the right side, i'd like to know how this can be achieved using just win32 api.

for an attempt, i created layered controls (listview, edit) on top of each other and used ShowWindow() to hide/show on selection but i don't think this is a good approach.

anyone got a suggestion?

cheers

Gunner

Don't know if it is the best way, but here is how I would do it:

Create a static control that will be the "parent" of your other controls (one for each node).  Create the controls "on" that static control, set their parent to the hwnd of that static control then subclass that static "parent" control to catch all the messages from the child controls.  Then when a node in the treeview is selected Show the one that you want.

Example:

; #######################################
; ###### Create holder
invoke CreateWindowEx, NULL, addr WndClsStatic, NULL,
WS_CHILD or WS_VISIBLE,
5, 25,
285, 315,
hWnd, NULL,
hInst, NULL
mov hParent1, eax

invoke SetWindowLong, hParent1, GWL_WNDPROC, addr ProcStaticCustom
mov OldStaticCustomProc, eax

; close button
invoke CreateWindowEx, NULL, addr WndClsButton, addr szClose,
WS_CHILD or WS_VISIBLE,
195, 285,
75, 20,
hParent1, IDC_CLOSE_CUSTOM,
hInst, NULL
invoke SendMessage, eax, WM_SETFONT, hFont, FALSE


~Rob (Gunner)
- IE Zone Editor
- Gunners File Type Editor
http://www.gunnerinc.com

donkey

Here's how I would do it, I prefer to use only dialogs since they are faster to develop in a dialog editor and the look can be made more consistent (I wrote this example in less than 30 minutes). I wrote this rather quickly but it works and switches very fast when compared to creating and destroying controls on the fly. The example only shows 2 panels but is scaleable to any number and the nesting etc.. of the treeview has no effect on it since each item contains its own panels handle. The real speed comes from how the TVN_SELCHANGED is handled, using lParam to store the handles you have only to execute 2 ShowWindow commands no matter how many child dialogs you have. I did not bother to translate it to MASM syntax so you will have to live with the GoAsm version. It will take some fine tuning of sizes and locations to make everything look right.

"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

dedndave

i am curious, Edgar
what program do you use as a dialog editor ?

donkey

Quote from: dedndave on April 04, 2010, 01:06:52 PM
i am curious, Edgar
what program do you use as a dialog editor ?

Hi Dave,

RadAsm
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

bozo

thanks Gunner and donkey for input/code.

i've gone with some code based on donkey's, even though positioning the dialog box seems to be a problem.

would be nice if there was a way to accurately calculate the position at runtime, any ideas on that?

I tried using GetWindowRect() for a group box "holder" and SetWindowPos() like you did with your own code donkey but it still required tweaking.

thanks!  :bg

donkey

Quote from: Kernel_Gaddafi on April 05, 2010, 04:09:31 PM
would be nice if there was a way to accurately calculate the position at runtime, any ideas on that?

You could put a static placeholder where you want the dialogs then get the position and size and delete the static. Use SetWindowPos to set the position and size of the dialogs based on the rect from the static control. Or you can use the way I usually get sizes and positions :

invoke GetWindowRect,[hTreeview],offset rect
invoke MapWindowPoints,HWND_DESKTOP,[hwnd],offset rect,2


You can then use the treeview to size the dialogs vertically and get the placement for the left side and top. The width is simply the remainder of the main dialog ie:

...continued from above...

// Stretch the width to the width of the dialog
invoke GetClientRect,[hwnd],offset rcDialog
mov eax,[rect.right]
add eax,4
sub [rcDialog.right],eax

mov eax,[rect.bottom]
sub eax,[rect.top]
mov [rcDialog.bottom],eax

add D[rect.right],2

// Show the first dlg keep the others hidden
invoke SetWindowPos,[hDlg1],NULL,[rect.right],[rect.top],[rcDialog.right],[rcDialog.bottom], SWP_NOZORDER + SWP_SHOWWINDOW
etc...
"Ahhh, what an awful dream. Ones and zeroes everywhere...[shudder] and I thought I saw a two." -- Bender
"It was just a dream, Bender. There's no such thing as two". -- Fry
-- Futurama

Donkey's Stable

bozo

hey, i've been playing around with your idea and instead of using dialogs, created individual windows.
i noticed something strange when there are more than 2 nodes in treeview to choose from.

let's say the nodes are:


  • Option 1
  • Option 2
  • Option 3

if the dialog box for option 1 is displayed first, and user selects option 3, option 1 dialog box will still be displayed.
haven't really debugged it yet, maybe it's mistake i've made..will report back

bozo

hehe..well, silly me.
just had to use the select item macro after initialization...

invoke TreeView_SelectItem,hTree,hOption1