Real Software Forums

The forum for Real Studio and other Real Software products.
[ REAL Software Website | Board Index ]
It is currently Wed Apr 08, 2020 2:50 am
xojo

All times are UTC - 5 hours




Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: Get ToolBar Buttons
PostPosted: Thu Sep 06, 2012 12:50 pm 
Offline

Joined: Thu Dec 16, 2010 1:22 pm
Posts: 188
Hello, I've been trying for the past 3 days (obviously unsuccessfully) to get information from a windows API that should return information about buttons in the System Tray.
I've found the handle to the System Tray, and can even get the button count. But when I iterate through them, even though the function returns true, none of the structure elements are populated...
As a test, I tried the function again, with lastbuttonindex+1 and it indeed returns false. So I know the function actually is working, it just isn't talking to me...

Please help.

Here's the API info
LRESULT WINAPI SendMessage(
_In_ HWND hWnd,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);


TB_GETBUTTON message
wParam
Zero-based index of the button for which to retrieve information.
lParam
Pointer to the TBBUTTON structure that receives the button information.


TBBUTTON Structure
typedef struct {
int iBitmap;
int idCommand;
BYTE fsState;
BYTE fsStyle;
#ifdef _WIN64
BYTE bReserved[6];
#else
#if defined(_WIN32)
BYTE bReserved[2];
#endif
#endif
DWORD_PTR dwData;
INT_PTR iString;
} TBBUTTON, *PTBBUTTON, *LPTBBUTTON;


and here's my code
Structure TBBUTTON
iBitMap as integer
idCommand as integer
fsState as byte
fsStyle as byte
bReserved1 as byte
bReserved2 as byte
dwData as integer
iString as integer
-----------------
dim b as Boolean
dim i as Integer

const WM_USER=&h400

dim TB_GETBUTTON as integer = WM_USER + 23
dim TB_BUTTONCOUNT as integer = WM_USER + 24

soft declare function FindWindowA lib "User32" (lpClassName as CString,lpWindowName as CString) as Integer
soft declare function FindWindowExA lib "User32" (hwndParent as integer, hwndChildAfter as integer, lpszClass as cstring,lpszWindow as cstring) as integer
// used for button count
soft declare function SendMessageABTC lib "User32" alias "SendMessageA" (hWnd as integer,msg as integer,wParam as integer,lParam as integer) as integer
// used for button info
soft declare function SendMessageABTN lib "User32" alias "SendMessageA" (hWnd as integer,msg as integer,wParam as integer,byref lParam as TBBUTTON) as Boolean

dim taskbarHandle as Integer
dim systrayHandle as Integer
dim sysPagerHandle as Integer
dim notifHandle as Integer

taskbarHandle=FindWindowA("Shell_TrayWnd",nil)
systrayHandle=FindWindowExA(taskbarHandle,0,"TrayNotifyWnd",nil)
sysPagerHandle=FindWindowExA(systrayHandle,0,"SysPager",nil)
notifHandle=FindWindowExA(sysPagerHandle,0,nil,"Notification Area")

dim buttoncount as integer
dim btn as TBBUTTON

buttoncount=SendMessageABTC(notifHandle,TB_BUTTONCOUNT,0,0)

for i =0 to buttoncount-1
b=SendMessageABTN(notifHandle,TB_GETBUTTON,i,btn) // returns true
next
b=SendMessageABTN(notifHandle,TB_GETBUTTON,buttoncount,btn) // returns false - as it should


Am I missing something simple?
The only thing I did encounter after looking at similar examples in VB and C++ (which actually sounds like it might be my issue) is verbage similar to the following
Quote:
Some of the required Win32 functions use structures to move information around. This works well if you and your target are in the same process space, but falls apart in our case. The naive implementation doesn't work. If you declare a structure, and get a pointer to it to pass into your function, the pointer is to some address in your virtual memory space. The function can't know this, and thinks that it is pointing to a block of its virtual memory.


And then the solution is using VirtualAllocEx and ReadProcessMemory (which is totally foreign to me) to store and retrieve the information.

I thought that was the whole idea behind passing pointers ala memoryblock/structure. Or is this some strange Windows quirk in this situation?

Thanks for any light anyone can shed on this!
and by the way, YES I am very green when it comes to Declares. :? So if I'm doing something wrong, please enlighten me.


Top
 Profile  
Reply with quote  
 Post subject: Re: Get ToolBar Buttons
PostPosted: Sat Sep 08, 2012 5:02 pm 
Offline

Joined: Sun Nov 26, 2006 11:01 am
Posts: 58
It's not working because SendMessageABTN(notifHandle,TB_GETBUTTON,i,btn) is storing the button-information in the adress-space of the process for this handle.

Here is a solution: http://www.codeproject.com/Articles/104 ... bar#Memory
When you got it, please let me see your implementation.

And use
notifHandle=FindWindowExA(sysPagerHandle,0,"ToolbarWindow32",nil)

instead of
notifHandle=FindWindowExA(sysPagerHandle,0,nil,"Notification Area")

because the title depends on users language.


Top
 Profile  
Reply with quote  
 Post subject: Re: Get ToolBar Buttons
PostPosted: Tue Sep 11, 2012 3:55 pm 
Offline

Joined: Thu Dec 16, 2010 1:22 pm
Posts: 188
That code example you pointed to was exactly the page I was quoting about why I thought it might not be working. :lol: So, yes, I already stumbled onto that "solution", however the implementation that it looks like it will require has me shaking in my boots! :shock: Later this week if I feel brave I might try to tackle it.

Thanks for the guidance/confirmation for why it wasn't working for me. I just need to figure out the solution now.

Thanks again. :D


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC - 5 hours


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group