//g_ptci->mask = TCIF_TEXT; or use this for txt
g_ptci->mask = TCIF_PARAM;
TabCtrl_GetItem(hTaskBar, 1, g_ptci);
Where hTasBar is the handle to the Tasbar (e.g. hWnd).
When ever I call TabCtrl_GetItem it causes an exception error...the handle to the window seems okay...as I can clear all the tabs and get the number of tabs using it.
Cannot get it to work either the only tab control macro that works is below, there must be a different approach to retrieving the handle to the taskbar, I even tried to attach handle to a CTabCtrl but still crashes.
Code:
int n = TabCtrl_GetItemCount( hTaskBar );
What exactly are you trying to achieve with your code.
Hi Shaun...I just don't understand why it won't work either.
I was going to modify the application taskbar button...try and put a CProgressCtrl in it.
I was talking to another person from PC-Magazine who said he solved the problem...see if you can make it out.
->
TabCtrl_GetItem(hTaskBar, 1, g_ptci); //causes a memory read error!????
This problem was also mentioned in the online article:
Also, I noticed that using a global, statically allocated TCITEM structure to retrieve information about taskbar buttons caused the same symptoms to appear: Explorer crashed and erratic results were returned by the TabCtrl_xxxxx functions. Using a dynamically allocated structure solved the problem, though the reasons why are not completely clear. When the structure is static, it's located in the BtnHook.dll data segment. When dynamically allocated, it's located on Explorer's process heap. Explorer apparently does something special with the control that is not compatible with static allocation.Also, I noticed that using a global, statically allocated TCITEM structure to retrieve information about taskbar buttons caused the same symptoms to appear: Explorer crashed and erratic results were returned by the TabCtrl_xxxxx functions. Using a dynamically allocated structure solved the problem, though the reasons why are not completely clear. When the structure is static, it's located in the BtnHook.dll data segment. When dynamically allocated, it's located on Explorer's process heap. Explorer apparently does something special with the control that is not compatible with static allocation.
Things appear to work the other way round in your case. I have never found any explanation to this problem. Maybe you could try static allocation...
Ben, managed another approach using COM, this will hopefully solve your problem, where the hWnd you would no what to do with it, I have just put together a source file for you.
Hi Shaun,
I've tried this code over and over again.....the problem with this code is I don't think the hWnd is the handle that is used in the Taskbar:-
/*------------------Section of code---------------------------------*/
OleInitialize(NULL);
What actually happens is the title and icon are used and added to the taskbar. The only way you can modify the taskbar is by getting its handle, then either SubClassing...or some other way.
I guess I'm doomed to forever wonder why it won't worrrkk {GetTab_Item(..)}
I know its possible to do custom drawn tabs! And the taskbar is only a tab control!
Thanx for the effort Shaun...really appreciate it.
If you ever find anything on your travels about it...please email me [email protected].
I have had a similar problem with TabCtrls and getting information about an item. After ~6 months of looking into it, I found a solution, but it is somewhat complex.
This assumes that the TabCtrl you are dealing with is in another process... of not then all bets are off . From reading your post, it looks like you are getting the handle to the taskbar, which is not in the same process as your calling application.
The problem is that the GetItem function passes a pointer to a TCITEM. That pointer is not valid in the other process's address space, so you get a memory exception. Getting the count and clearing the tabs works because those functions do not pass a pointer.
So... how to get this to work?? Like I said, it is somewhat complex:
First, you need to get to the other process's address space (the taskbar's in this case). To do this, you need to inject a DLL into that process using the SetWindowsHookEx function. When the DLL is injected, it can access the other process's address space.
In the DLL, you need to have some way of communication, so you create an invisible dialog when the DLL is attached (at least thats the way I did it), and communicate with it via the WM_COPYDATA message. Using this message, you can tell the DLL to get the info of a TabCtrl item using the TabCtrl macros (TabCtrl_GetItem, etc), and also pass it all information necessary (HWND, item id). The function will work because it is now in the remote process's address space.
Next, to get the information, (in this example the text of the item), you can create a memory mapped file using the DLL, which the calling process (your application) can access. You copy the data you are interested in to the memory mapped file, and send a message back to your application (WM_NULL or WM_COMMAND is fine) telling it to open the memory mapped file and grab the data.
Then you unhook the hook using UnhookWindowsHookEx() when you are done.
Of course, there are a lot of details in the implementation... my suggestion is to check out a book by Jeffrey Richter called Advanced Windows Programming. In it, he has some sample code that shows how to do all I mentioned above. The sample code is in the included CD, not in the text of the book, unfortunately. This is where I learned how to do the method...
I have been using this method for some time to get the text for a TabCtrl item, and I know of no other way to do it. Unfortunately, it requires the creation of a new DLL. Again, this method assumes the TabCtrl is in another process.
However, I cannot get this method to work with the TCN_SELCHANGE message (via WM_NOTIFY)... the message gets through and changes the Tab, but when the Tab's focus changes I get a crash, so I think it doesnt involve this method... If anyone has any ideas on this, I'd appreciate it .
I hope this helps, and at least sends you in the right direction. Its probably more info than you wanted!!!
Thanx for the feedback JohnnyCoder, it really is a help to know that someone else has had the problems I'm having.
Again I used a similar method...but I injected the dll into the other applications memory space using VirutalAllocEx and VirutalFreeEx, and kept the code in the dll...that way I didn't use memory maps.
A piece of code on the net that you should look at on TabCtrls and the system Tab is a program called button boogie (just type it in the search engine google and you'll find it easy). It lists how to use dll's to implement a similar method...but it uses a different method...invoving the registry and things...which I didn't have time for at the time.
But I'll definetly be getting the book by Jeffrey Richter called Advanced Windows Programming now...just to have a read.
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.