hi guy, i'm a poor french coder trying to learn asm win32, and it's very difficult ;)
i have a question for you, about toolbar and tooltip, my tooltips for the toolbar's buttons aren't work, i don't understand because of what.

my snippet code :




LOCAL tbb : TBBUTTON
LOCAL tbad : TBADDBITMAP
LOCAL hBitmap : DWORD

invoke LoadBitmap, hInstance, IDB_TOOLBAR
mov hBitmap, eax

invoke CreateToolbarEx, hWnd, WS_CHILD or TBSTYLE_TOOLTIPS or WS_CLIPSIBLINGS,
IDC_TOOLBAR, 0, NULL, NULL, NULL, 0, 20, 23, 22, 22, SIZEOF TBBUTTON

mov hToolbar, eax

;invoke SendMessage, hToolbar, TB_GETTOOLTIPS, 0, 0
;mov hTooltip, eax

;###########################################################
; POUR METTRE LES ICONES DE WINDOWS
;###########################################################
;===========================================================
invoke RtlZeroMemory, ADDR tbad, SIZEOF TBADDBITMAP
;==========================================================
mov dword ptr [tbad.hInst], 0
push hBitmap
pop dword ptr [tbad.nID]
invoke SendMessage, hToolbar, TB_ADDBITMAP, 1, ADDR tbad
;==========================================================

invoke RtlZeroMemory, ADDR tbb, SIZEOF TBBUTTON
;==========================================================
; METTRE NULL dans le BMP ID et l'instance
;==========================================================
mov word ptr [tbb.iBitmap], 0
mov word ptr [tbb.idCommand], IDM_NOUVEAU
mov byte ptr [tbb.fsStyle], TBSTYLE_BUTTON
mov byte ptr [tbb.fsState], TBSTATE_ENABLED
invoke SendMessage, hToolbar, TB_ADDBUTTONS, 1, ADDR tbb
;==========================================================
invoke ShowWindow, hToolbar, SW_SHOW
;==========================================================


i put juste one button for the example.
and after my code to display the tooltip, i try to display a msgbox first to see if the msg is sent but not




.ELSEIF eax == WM_NOTIFY

mov ebx, dword ptr [lParam]
mov eax, dword ptr [ebx+8h]

.IF eax == TTN_NEEDTEXT


invoke MessageBox, NULL, ADDR szTest, ADDR szTest, NULL

.ENDIF



i also try :




.ELSEIF eax == WM_NOTIFY

assume edi : PTR NMHDR
mov edi, lParam


.IF [edi].code == TTN_NEEDTEXT


invoke MessageBox, NULL, ADDR szTest, ADDR szTest, NULL

.ENDIF


i think that i do an idiot error but i don't find, thanx to your help and sorry for my bad english
cya :)
Posted on 2003-04-13 16:59:29 by SpYflaX
maybe like this

.ELSEIF uMsg == WM_NOTIFY
mov edx,lParam
mov eax,.NMHDR.code

.IF eax == TTN_NEEDTEXT

.ENDIF
Posted on 2003-04-13 17:07:08 by donkey
thx you guy but it's not work ;) another suggestions ? :)
Posted on 2003-04-14 16:41:28 by SpYflaX
OK, here's some working code that uses the same idea. In this case, the tip text is in the RC file as a stringtable entry. So if I have a button like:

TBBUTTON <STD_HELP, 1910, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0>

then in the RC file I has an entry like this in STRINGTABLE:

2910,"Help"

Notice the difference of 1000, hence the add. Also notice the max length of 16 bytes, but that's easy to change if you want:

tbTips  db 16 dup (0)

...
.elseif uMsg == WM_NOTIFY
mov eax, lParam
mov eax, (NMHDR PTR [eax]).code
.if eax == TTN_NEEDTEXT
mov eax, lParam
mov eax, (NMHDR PTR [eax]).idFrom
add eax, 1000
invoke LoadString, hInst, eax, ADDR tbTips, 16
mov eax, lParam
mov (TOOLTIPTEXT PTR [eax]).lpszText, OFFSET tbTips
.endif


:)
Posted on 2003-04-14 21:22:36 by S/390
Here's an "optimized" version, that uses EBX :grin:

.elseif uMsg == WM_NOTIFY

mov ebx, lParam
mov eax, (NMHDR PTR [ebx]).code
.if eax == TTN_NEEDTEXT
mov eax, (NMHDR PTR [ebx]).idFrom
add eax, 1000
invoke LoadString, hInst, eax, ADDR tbTips, 16
mov (TOOLTIPTEXT PTR [ebx]).lpszText, OFFSET tbTips
.endif
Posted on 2003-04-14 21:54:47 by S/390
oki thx, i will try, in any case, i thank you too much for your help ;)
Posted on 2003-04-15 11:07:15 by SpYflaX
You can ofcourse just do it this way if you are putting the strings in a stingtable, much faster
2910,"Help"


.elseif uMsg == WM_NOTIFY
mov ebx, lParam
mov eax, (NMHDR PTR [ebx]).code
.if eax == TTN_NEEDTEXT
mov eax,hInst
mov (TOOLTIPTEXT PTR [ebx]).hinst,eax
mov eax, (NMHDR PTR [ebx]).idFrom
add eax,1000
mov (TOOLTIPTEXT PTR [ebx]).lpszText,eax
.endif
no need to load the string at all if you specify an instance handle, the function will load it for you. If you don't use the direct method be sure you set the hInst member to NULL or there may be data present if it is not initialized.
lpszText

Pointer to a string that contains or receives the text for a tool. If hinst specifies an instance handle, this member must be the identifier of a string resource.
Posted on 2003-04-15 13:08:57 by donkey
really, really thanx for your help ;)
... i don't try your method but at the beginning, my msgbox wasn't display, the msg wasn't sent by the application
i say that in cas of ... :)
Posted on 2003-04-15 14:49:26 by SpYflaX
But you are getting the TTN_NEEDTEXT message now right ? I had assumed that you had solved the problem of the toolbar not sending the message to your app. I was just showing a way to crush the code down even further
Posted on 2003-04-15 15:18:22 by donkey
if i put this in my code :

szTest db "szTest", 0
...
.elseif uMsg == WM_NOTIFY
mov ebx, lParam
mov eax, (NMHDR PTR ).code
.if eax == TTN_NEEDTEXT
invoke MessageBox, NULL, ADDR szTest, ADDR szTest, NULL
.endif

i should have a messagebox displayed when i stay on a button during few second, no ?
because it's doesn't work :)
Posted on 2003-04-15 15:43:42 by SpYflaX
Yes, it should be displayed. Is the toolbar created with TBSTYLE_TOOLTIPS and is the parent handle the right one, ie the one that is associated with the procedure that you are checking for the message? I would begin by verifying that the toolbar parent handle is correct.
Posted on 2003-04-15 15:53:15 by donkey
Just as a dumb question, you did assign button text in iString field of the TBBUTTON structure right ?
Posted on 2003-04-15 16:11:52 by donkey
....
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
...
push hWnd
call ToolbarCreation
...

ToolbarCreation proc hand:HWND
...
invoke CreateToolbarEx, hand, TBSTYLE_TOOLTIPS or WS_CHILD or WS_CLIPSIBLINGS,
IDC_TOOLBAR, 0, NULL, NULL, NULL, 0, 20, 23, 22, 22, SIZEOF TBBUTTON
..

the handle is the handle of my parent window, i'm sure, i have even check under softice ;)
anothers idea, perhaps my way to create the toolbar ? i don't know

it's very nice to you to help me :) and sorry for my english

if you have a masm entire code to manage a toolbar with tooltip, it's interess me

bye
Posted on 2003-04-15 16:37:43 by SpYflaX
i'm not fill the field iString in my struct TBBUTTON, it's a problem?
Posted on 2003-04-15 16:41:27 by SpYflaX
I think that the text that you set for the button is used with the tooltip control for the toolbar. I think that if you want to use the LPSTR_TEXTCALLBACK you have to set a different tool for the control and assign each button individually. I have checked my docs and the only reference I can find is that the toolbar displays the text in the iString field as it's tooltip. I'll try to set up a toollbar in something and get back to you...
Posted on 2003-04-15 16:59:09 by donkey
I created a toolbar as follows :
.data

TBBtnArray TBBUTTON <NULL,5001,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0>
TBBUTTON <NULL,NULL,TBSTATE_ENABLED,TBSTYLE_SEP,0,0>
TBBUTTON <NULL,5002,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0>
TBBUTTON <NULL,5003,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0>
TBBUTTON <NULL,NULL,TBSTATE_ENABLED,TBSTYLE_SEP,0,0>
TBBUTTON <NULL,5004,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0>
TBBUTTON <NULL,5005,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0>
TBBUTTON <NULL,5006,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0>
TBBUTTON <NULL,NULL,TBSTATE_ENABLED,TBSTYLE_SEP,0,0>
TBBUTTON <NULL,5007,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0>
TBBUTTON <NULL,5008,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0>
TBBUTTON <NULL,NULL,TBSTATE_ENABLED,TBSTYLE_SEP,0,0>
TBBUTTON <NULL,5009,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0>
TBBUTTON <NULL,NULL,TBSTATE_ENABLED,TBSTYLE_SEP,0,0>
TBBUTTON <NULL,5010,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0>
.code
mov wc.cbSize,SIZEOF WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc, OFFSET WindowProc
mov wc.cbClsExtra,NULL
mov wc.cbWndExtra,NULL
mov eax,hInst
mov wc.hInstance,eax
mov wc.hbrBackground,COLOR_BTNFACE + 1
mov wc.lpszMenuName,NULL
mov wc.lpszClassName,OFFSET MainWndClass
invoke LoadIcon,hInst,MainICO
mov wc.hIcon,eax
mov wc.hIconSm,eax
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor,eax
invoke RegisterClassEx, addr wc

Invoke CreateWindowEx,WS_EX_APPWINDOW,ADDR MainWndClass,\
ADDR szFormCaption,WS_THICKFRAME or WS_SYSMENU or WS_OVERLAPPED,\
100,100,400,120,\
NULL,NULL,hInst,0

mov hMainWindow,eax

invoke CreateToolbarEx, hMainWindow,WS_VISIBLE or \
WS_CHILD or TBSTYLE_TOOLTIPS or WS_CLIPSIBLINGS,\
1003, 0, NULL, NULL, NULL, 0, 20, 23, 22, 22, SIZEOF TBBUTTON
mov hToolbar, eax

invoke SendMessage,hToolbar,TB_ADDBUTTONS,15,ADDR TBBtnArray
invoke SendMessage,hToolbar,TB_AUTOSIZE,0,0
and it sent the TTN_NEEDTEXT Message properly. to the following routine:
.ELSEIF uMsg == WM_NOTIFY

mov edx,lParam
mov eax,[edx].NMHDR.code
.IF eax == TTN_NEEDTEXT
invoke MessageBox,NULL,ADDR DlgError,NULL,MB_OK
.ENDIF
Posted on 2003-04-15 17:14:25 by donkey
it is late in france, I would try that tomorrow
in any case, thanks for having to help me until the end, you are too sympathetic ;)
I keep you informed tomorrow

merci, thx :)
Posted on 2003-04-15 17:18:27 by SpYflaX
Bon soir, a demain...

Here is the progam, it just creates a few buttons and a toolbar then uses string table entries to set the text of the tooltips (I use the RadASM IDE so it is in that project format)
Posted on 2003-04-15 19:59:40 by donkey
great, i success thanks to you and your program :)
Merci beaucoup donkey :)

i find my error :

.WHILE TRUE
--> invoke GetMessage, ADDR msg, hwnd, 0, 0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW

replace by

.WHILE TRUE
invoke GetMessage, ADDR msg, NULL, 0, 0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.ENDW

it's strange :)
all for that, i always put hwnd but now i know what i must put :)
Posted on 2003-04-16 15:53:16 by SpYflaX
Hey donkey, thanks for that shortcut. I like it when we can skip an entire API call... :grin:

But after doing a little reading of WIN32.HLP, it turns out we can dump another 2 movs. Check this out:

hinst

Handle to the instance that contains a string resource to be used as the tooltip text. If lpszText is the pointer to the tooltip text, this member is NULL


So we can cut it down even further, to this:

.elseif uMsg == WM_NOTIFY

mov ebx, lParam
mov eax, [ebx].NMHDR.code
.if eax == TTN_NEEDTEXT
mov eax, [ebx].NMHDR.idFrom
add eax, 1000
mov [ebx].TOOLTIPTEXT.lpszText, eax
.endif


Works fine on 95B. I'll try in on 2K tomorrow. :cool:
Posted on 2003-04-17 20:18:09 by S/390