News:

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

tab controls

Started by Slugsnack, January 03, 2010, 02:24:46 AM

Previous topic - Next topic

Slugsnack



i've used tab controls in the past but lost my last source code and this time it's messing up on me. i'm loading a child dialog into the tab but it's being loaded across from the side of the tab. i had expected it to be loaded at the left most side but instead there is a gap there.

i've tried, unsuccessfully, to use TCM_ADJUSTRECT to fix this. i can actually move the child window to where i want by hardcoding coordinates and then using setwindowpos() but as always i am sure there is an elegant way that i'm missing out on.

modified the bare skeleton what has been done up there

Ghandi

#1
You can get the size of the parent dialog or the tab strip with GetClientRect and then use MoveWindow to set the size of the tab dialog within the window borders. You can use the rect sizes to place the tabbed dialogs within the parent window at *any* possible position/size.

HR,
Ghandi

donkey

The problem appears to be in your creation of the tab dialog...

From your resource file:

IDD_PATHSETTINGS DIALOGEX 20,15,178,71

This sets the initial placement of the tab at 20,15 you will most likely have to adjust it (probably to 0,15 or something close to that). In order to do this in RadASM just adjust the left and top fields of the dialog in the dialog editor.

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

Slugsnack

Quote from: Ghandi on January 03, 2010, 03:07:45 AM
You can get the size of the parent dialog or the tab strip with GetClientRect and then use MoveWindow to set the size of the tab dialog within the window borders. You can use the rect sizes to place the tabbed dialogs within the parent window at *any* possible position/size.

HR,
Ghandi
the client rect of a tab control starts from its top left, including the tab itself so that is not useful. i think it is the 'display rect' which is needed which i have failed to get
Quote from: donkey on January 03, 2010, 07:02:56 AM
The problem appears to be in your creation of the tab dialog...

From your resource file:

IDD_PATHSETTINGS DIALOGEX 20,15,178,71

This sets the initial placement of the tab at 20,15 you will most likely have to adjust it (probably to 0,15 or something close to that). In order to do this in RadASM just adjust the left and top fields of the dialog in the dialog editor.

Donkey
thank you donkey, that was just the problem :P

i set it at 1, 12 at the moment and it looks like this :


do you know if there is any convention in terms of layout coordinates ? should a small border be left between the child and the tab control ? does it look odd at the moment ? actually i'm a bit against hardcoding coordinates in the first place :|

( i really suck at making my GUIs look nice )

Ghandi

Quotethe client rect of a tab control starts from its top left, including the tab itself so that is not useful.

Quoteparent dialog or the tab strip
Hmm, dont like the size of the tab rect? Use the main window's then.

Think outside the box for a second before saying that. You get the rect, use it as your base.... So, get the rect and add to the top value so you arent going to display your dialog(s) over the tabs themselves. Then, you need to subtract from the bottom value else you'll set it over the bottom of your dialog. I must apologize there, i thought that offsetting from the base values of the rect was an obvious thing to do to prevent oversizing the child dialog(s) and/or controls.

Before you say that this method is not useful, you should consider that any resizable dialog needs a mechanism to resize and reposition dialog components, hence the use of a common starting point (the rect of the parent window for instance) and no matter what resizing is done, the dialog will remain in proportion with itself.  Even if you dont want your main window resizable, you can formulate your layout so you can base it all off your main windows size, still keeping it in proportion.

Sorry i said anything, next time i'll just keep my mouth shut.

HR,
Ghandi

Slugsnack

Quote from: Ghandi on January 03, 2010, 05:06:38 PM
Quotethe client rect of a tab control starts from its top left, including the tab itself so that is not useful.

Quoteparent dialog or the tab strip
Hmm, dont like the size of the tab rect? Use the main window's then.

Think outside the box for a second before saying that. You get the rect, use it as your base.... So, get the rect and add to the top value so you arent going to display your dialog(s) over the tabs themselves. Then, you need to subtract from the bottom value else you'll set it over the bottom of your dialog. I must apologize there, i thought that offsetting from the base values of the rect was an obvious thing to do to prevent oversizing the child dialog(s) and/or controls.

Before you say that this method is not useful, you should consider that any resizable dialog needs a mechanism to resize and reposition dialog components, hence the use of a common starting point (the rect of the parent window for instance) and no matter what resizing is done, the dialog will remain in proportion with itself.  Even if you dont want your main window resizable, you can formulate your layout so you can base it all off your main windows size, still keeping it in proportion.

Sorry i said anything, next time i'll just keep my mouth shut.

HR,
Ghandi
umm what i mean is when i did getclientrect for the tab control it returns the rect starting from the top left, including the clickable part where i do not want to display anything. in this case the hardcoding of the initial coordinates works fine because that dialog is not meant to be resized at all.

it sounds like you took my first reply quite negatively ? i'm sorry that that happened and it was not my intention if that is how i came across.

i appreciate you taking your time to post your expertise to help me. thank you :]

Ghandi

I didnt take it negatively, you said it wasnt useful. If you take the client rect of your window and add the size of your tabstrip to the top value, you can skip overlaying the tabs. it will mean your top value for the child dialogs will be under the tabs. Which is why i said about making the bottom value smaller also, as its based off your top value.

I dont pretend to have any expertise, i'd call myself a newbie still, i was just trying to share a concept that you might find useful sometime. Sorry if i came across as anything else. Peace and Happy New Year.

HR,
Ghandi

donkey

You can get the bounding rectangle of the tab strip without the client area using the TCM_GETITEMRECT message. The returned RECT is in viewport coordinates but that generally doesn't make a difference since the origin is usually 0,0. You can verify the origin of the viewport using GetViewportOrgEx but I would be surprised if you actually used viewport coordinate space for something like a tab strip. So for a standard run-of-the-mill tab control you would do this...

invoke SendMessage,[hTab],TCM_GETITEMRECT,0,offset rect

If you wish to verify the viewport:

invoke GetDC,[hTab]
push eax
invoke GetViewportOrgEx,eax,offset pt
pop eax
invoke ReleaseDC,[hTab],eax


Make sure you have added text to tab 0 before you send this message as the height is adjusted based on the font used. Generally speaking the result is usually 20 pixels high with the standard font.

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

xandaz

   Hi again guys. I have a questions about something - in this case related to a tab control but not really. I was processing TCN_SELCHANGE and did this:
.if [lParam.NMHDR].code==TCN_SELCHANGE
... which did nothing.
   Then i used:
mov eax,lParam
assume eax:PTR NMHDR
... end it works.

can someone tell me why it doesnt work the first time around?
thanks


donkey

It was not the right address, since lParam is LOCAL, it is simply an offset from EBP or ESP, not the actual address so you have to dereference it in a register first. For example lParam is assembled as EBP+20h (a memory address), you need the data at [EBP+20h] and then to add your offset to that value, that must be done with a second register. Doing it with the lParam label you are actually getting a different memory address than lParam:

lParam + NMHDR.code = ESP+20h+8h which would be somewhere in your local stack (likely a saved register).
"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

xandaz

   Thanks donkey. Someone already explained it some time ago but it wasn't clear in my head. Thanks a lot a again for explaining.
   Best regards to all.

xandaz

   I had this done a while back but i never remembered to post it. here it goes.
   Thanks a lot guys.

Twister

This may be not be helpful, but ..

How in the world did you get your application to look for slick and neat??!

Usually when I make a GUI application using just solely the WINAPI, it turns out to have the look of a VB5 or VB6 application. :(

xandaz

    Damn... i'm not sure i understand you GTX. Is that for me? Do you mean it looks good? well... reply later... i wanna know...
    Bye guys.

Slugsnack

include the xp style manifest