|
Hi I am developing a deskband and have installed the RBDeskBand wizard. And it work great, espcially compared to the MSJ and MSDN examples on deskbands.
But I have a problem in the development process.
I compile and then call regsvr32 on the dll to test it, then when I have to make some changes I first call regsvr32 /u MyBands.dll to remove it from the Toolbars popup menu. But when I recompile VC can't link because the OS has a lock on the MyBands.dll file.
How do I force the OS not to lock this file so I don't have to reboot each time I compile ?
-Jan
|
|
|
|
|
Jan,
First the reason for the problem. Deskbands once loaded are loaded for the life of the user session. The only way to unload it is to log off and log back on or reboot, if you don't know some tricks.
There are a couple of ways you can work around this when trying to develop a deskband. First workaround is to register it initially for debug purposes as a Communications band and do all your debug work within Interent Explorer. The second way is to kill the explorer.exe process in taskmanager before recompiling. If the explorer.exe process does not automatically restart, from the File|New Task menu item in Task Manager you can restart the explorer process yourself.
These are the 2 workarounds that I use when developing deskbands that don't resort to rebooting or logging off.
-Erik
|
|
|
|
|
Not entirely true. If you close down all instances of Internet Explorer and recompile, it works. I've tried this successfully on Windows 98 and Windows 2000, despite IE being part of the shell. See, only the IE control exposing IWebBrowser2 is loaded into the shell. The IE container is what enumerates the IDeskBand objects. If you close down all instances of the container, you should be okay.
This is using both IE5 and IE6b.
---
Heath Stewart
Systems Administrator / Developer
EsotericRealm / Palisade Systems
http://www.esotericrealm.com/~hstewart
|
|
|
|
|
Forgot to mention, what I typed above is only valid if you created an instance of your control in Internet Explorer. If you did it via Windows Explorer, then Erik is right. It's better, therefore, to just test your desk band in Internet Explorer. It uses a separate container than Windows Explorer, although both enumerate IDeskBand objects and can host them via IObjectWithSite.
---
Heath Stewart
Systems Administrator / Developer
EsotericRealm / Palisade Systems
http://www.esotericrealm.com/~hstewart
|
|
|
|
|
How can i take the view that i get from the wizard and take turn it into html file or url?
anybody?
|
|
|
|
|
I have added a sample project that contains a CWindowImpl class called CHTMLPageWnd. This class creates a HTML control in the window and loads a HTML page from a resource within the component. It does nothing fancy but provide a starting point for you to continue with your endeavors.
Hosted Web page resource
Cheers,
-Erik
|
|
|
|
|
hi,
thanks again..
Finally I installed Band Object in my IE.
But I can't clean the registry with DllUnregisterServer().
After I do this.. "Regsvr32 /u MyBand.dll"
there remains a key in my registry.
I think Category manager function below doesn't work properly.
....pcr->UnRegisterClassImplCategories(CLSID_Band, 1, &(CATID)CATID_InfoBand);
Can I use RGS file instead of Category manager function?
Anyway my buggy code is as follows.
-> This is what's left in my registry after DllUnregisterServer().
....HKEY_CLASSES_ROOT\CLSID\{06C8BE74-6666-4A8F-9D9F-A4B472FE3A3B}\
..........Implemented Categories
-> And here's my DllUnregisterServer() code.
STDAPI DllUnregisterServer(void)
{
...CoInitialize(NULL);
...ICatRegister* pcr = NULL;
...HRESULT hr = CoCreateInstance (CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister,(LPVOID*) &pcr);
...if(SUCCEEDED(hr) && pcr)
...{
......// CATID_CommBand, CATID_InfoBand, or CATID_DeskBand
......hr = pcr->UnRegisterClassImplCategories(CLSID_Band, 1, &(CATID)CATID_InfoBand);
......pcr->Release();
...}
...CoUninitialize();
#ifdef _MERGE_PROXYSTUB
...PrxDllUnregisterServer();
#endif
...hr = _Module.UnregisterServer(TRUE);
...return hr;
#include "Band.h"
}
-> This is my DllRegisterServer() and the result in my registry.
STDAPI DllRegisterServer(void)
{
#ifdef _MERGE_PROXYSTUB
...HRESULT hRes = PrxDllRegisterServer();
...if (FAILED(hRes))
......return hRes;
#endif
..._Module.RegisterServer(TRUE);
...CoInitialize(NULL);
...ICatRegister* pcr = NULL;
...HRESULT hr = CoCreateInstance (CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER, IID_ICatRegister,(LPVOID*) &pcr);
...if(SUCCEEDED(hr) && pcr)
...{
......// CATID_CommBand, CATID_InfoBand, or CATID_DeskBand
......hr = pcr->RegisterClassImplCategories(CLSID_Band, 1, &(CATID)CATID_InfoBand);
......pcr->Release();
...}
...CoUninitialize();
...return SUCCEEDED(hr);
}
....HKCR\CLSID\{06C8BE74-6666-4A8F-9D9F-A4B472FE3A3B}
.........Implemented Categories{00021493-0000-0000-C000-000000000046}
.........InprocServer32
.........ProgID
.........Programmable
.........TypeLib
.........VersionIndependentProgID
|
|
|
|
|
hwan,
Yes I know there are problems. Even more may exist with the proxy stub options, MTS, and support for MFC. I will check all these cases before distributing the next version of my band.
Cheers,
-Eri
|
|
|
|
|
If you're using an RGS file in your project, you can add the "ForceRemove" identifier before your CLSID = s '{<guid>' to force a remove on DllUnregister or to remove it before adding back again via DllRegister.
---
Heath Stewart
Systems Administrator / Developer
EsotericRealm / Palisade Systems
http://www.esotericrealm.com/~hstewart
|
|
|
|
|
hi,
thanks for the answer last time.
This time,...
I fixed DllRegisterServer(..) and build the code.
Then I tried to register the DLL file created like this,
RegSvr32 TestBand.dll
But nothin appears in IE. No Band Object available...
But I found the Band Object installed after I reboot
my computer.
What's wrong with my system?
I think the source of problem is the registry data of my own. I'm using window2000 professional.
Please give me any hint that you can think of on this kind of problem.
hwa
|
|
|
|
|
Yes I know there are a few issues with the wizard. I am working on fixes for them today. The issue may be that there is no threading model set. add the threading model to the registry script of your project.
Let me know if that still doesn't fix it.
Cheers,
-Eri
|
|
|
|
|
I created empty "ATL COM AppWizard" project,
which will make In-Proc dll with merged Proxy-Stub code.
Then I inserted this "DeskBand" object.
After that, I was going to correct the code of
DllRegisterServer function, as you directed on this page.
But I couldn't understand the comment given in the function.
It says I should remove 'return' keyword, after which
I couldn't compile the file.
Did I misunderstand the direction given?
Please help me with the code...
Here's my DllRegisterServer(),
STDAPI DllRegisterServer(void)
{
#ifdef _MERGE_PROXYSTUB
HRESULT hRes = PrxDllRegisterServer();
if (FAILED(hRes))
return hRes;
#error Code Section Has not been moved!!!
// REMARKS:
// Due to a limitation of the ATL Object creation wizard
// language, You need to manually remove the
// "return" keyword from infront of "_Module.RegisterServer
// (TRUE)". Then remove the #error line and
// these remarks.
CoInitialize(NULL);
ICatRegister* pcr = NULL;
HRESULT hr=CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL,CLSCTX_INPROC_SERVER, IID_ICatRegister,(LPVOID*) &pcr);
if(SUCCEEDED(hr) && pcr){
// CATID_CommBand, CATID_InfoBand, or CATID_DeskBand
hr = pcr->RegisterClassImplCategories(CLSID_LuckBand, 1, &(CATID)CATID_InfoBand);
pcr->Release();
}
CoUninitialize();
return SUCCEEDED(hr);
#endif
// registers object, typelib and all interfaces in typelib
return _Module.RegisterServer(TRUE);
}
|
|
|
|
|
Yes I know the code needs to be revised and I need to build a new version. Here's the solution to your problem. What I did was move the band registration code down where it should be and did what the code would have generated if proxy stub was not used.
Hope it helps,
-Erik
Revised: DllRegisterServer
STDAPI DllRegisterServer(void)
{
#ifdef _MERGE_PROXYSTUB
HRESULT hRes = PrxDllRegisterServer();
if (FAILED(hRes))
return hRes;
#endif
// registers object, typelib and all interfaces in typelib
_Module.RegisterServer(TRUE);
CoInitialize(NULL);
ICatRegister* pcr = NULL;
HRESULT hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL,CLSCTX_INPROC_SERVER, IID_ICatRegister,(LPVOID*) &pcr);
if(SUCCEEDED(hr) && pcr){
// CATID_CommBand, CATID_InfoBand, or CATID_DeskBand
hr = pcr->RegisterClassImplCategories(CLSID_LuckBand, 1, &(CATID)CATID_InfoBand);
pcr->Release();
}
CoUninitialize();
return SUCCEEDED(hr);
}
|
|
|
|
|
Is there any good way add a chevron to this or any other user deskband? Only thing I can think of doing is adding a gripperless rebar control inside the deskband, but that feels kludgy...Any ideas
|
|
|
|
|
Kyle,
There are alternatives. I weighed the possibility of using a rebar control in my deskband for the Color Picker so I could use the drop down arrows. But it also felt kludgy, So I created a button class that associated itself with a parent window that was notified when the dropdown arrow (button) was being pressed so it could react. You could do something similar. Create a button that reacts like it would in a rebar control. Have it float on top of the parent and have it send messages to the parent as the chevron would do in the rebar control. In my opinion it would be less kludgy and give you more control over the chevron and it's parent.
Hope this helps,
-Eri
|
|
|
|
|
The generated code doesn't work, even after making the required changes to DLLRegisterServer.
For starters, the .rgs script doesn't include a ThreadingModel entry, which means simply compiling the generated code will result in a non-working band object that doesn't create. You need to add a ThreadingModel = "Apartment" registry entry.
Next, the code is inefficient, and in some cases silly. Instead of modifying the DLLRegisterServer code, it should just use a category map for registering the category ID. One macro, and the generated code can compile without modification.
Next, the object should really be deriving from CWindowImpl instead of creating a window with CreateWindow. You can even go one step further and use the subclassing macros to simply subclass a STATIC.
Finally, while it's a bit silly, the deskband doesn't repaint the static control when it's resized, you need to either invalidate the control on the WM_SIZE handler, or modify the class style to add CS_HREDRAW and CS_VREDRAW.
I've actually written a completely new ATL Object Wizard which creates a much better DeskBand shell. I'll probably be posting it soon. It's based very loosely on Erik T's generated code, but is almost a complete rewrite.
|
|
|
|
|
Erik,
It's unfortunate that you feel you wasted time with the ATL Object Wizard, but to respond to your comments.
The code does work, but you can only create a single instance of the deskband in IE because it defaults to Single Threading since the ThreadingModel is not defined. This is a known issue that I found last week and have fixed it in my code but have not posted an update as of yet.
Yes I could use a category map, it was suggested by someone a few days ago, but I like most people am busy and can not always updates to my posts as immediately as I would like.
As for the static control. It is a placeholder, It was one code line that could be replaced easily with the users specfic UI implementation. I did it for simplicty so that it could be removed quickly and not have to hunt down useless code that would more likely be removed. Then the developer could use my CWindowImpl ATL Object wizard and get the UI base implementation that they want.
As for the repainting issue, This is not a concern since the code line would be removed as stated previously.
The ATL Object Wizard is to be a base for which you develop your own bands, as stated in the article. It is just a starting point for anyone wanting to develop a desk band.
I believe that the code is efficent, except for the lack of smart pointers, which was not included since not everyone knows how to use them. I went with the least common denominator an simplicity. If you had suggested comments to me, I could have made the changes quickly and effortlessly, and you could have moved forward.
Cheers,
-Eri
|
|
|
|
|
Actually, the compiled code simply does not work under both NT4 with IE 5, or Windows 2000 with IE 5.5. The object get's installed (and after some dinking around with the IE cache settings) shows up in the toolbars listing. But selecting the bar does nothing. It doesn't instantiate the object.
I spent 3 days trying to figure out this problem, and it simply did not work. I'm the one that actually suggested to you the other day about the category map, however you never responded back to me. So I assumed you were no longer reading email on the subject. In my mail to you, I asked you about the problem with instantiating the object, and yet you did not respond. So, I take your comment about "suggesting comments to you" lightly, since you did not respond to my email at all.
It's easy to test this problem, simply remove the ThreadingModel keyword from the registry entry for the object, and try to create the bar. It doesn't create. Adding the registry entry, it creates.
My comment about the static was simply to make the control complete, even if it is meant as a placeholder. I feel if you post sample code, it should be as complete as possible, with comments describing anything you feel might be confusing, rather than choosing a less optimum method. Since it's an ATL sample, it should use ATL completely, which includes use CWindowImp for creation of the controls window.
I might note that your CWindowImpl wizard was released yesterday, yet your DeskBand wizard was released many months ago. I fail to see how users could have used a wizard which did not exist to add something that should have been there in the first place. All users will need a window for their DeskBar, and as such, I don't see how adding a CWindowImpl derivation would have been something they would have removed. The only they needed to remove was one macro which subclasses the static and replace it with a macro to define their own window class.
The repainting issue is again, a service to the people that use your code. In my first message, I said that it wasn't really a big deal, and that it was a bit silly. If they follow your example, and get a control that doesn't repaint when they resize it, they spend hours trying to solve a problem which would have never come up if the sample had been complete. Lots of users may well use your code, simply because they only need a a static control in there.
There are other issues as well, which I didn't raise at first. For instance, your sample derives from IPersist, IOleWindow and IDockingWindow. These are all unneccessary, as IDeskBar and IPersistStream already derive from these, and your object derives from IDispatch, which is completely unneccessary, since DeskBands are not used by things like VB or other automation controllers. Additionally, your sample creates a I<projectname>, which is also unnecessary, since a deskband object only supports the standard interfaces.
If your goal was to be simplistic, and not confuse people, then you shouldn't include all that extra cruft. And should have included more comments.
If you want, I'll send you my rewritten sample.
I'm grateful for your project to begin with. I'm sorry for saying negative things, but I thought you wanted constructive criticism and feedback.
|
|
|
|
|
Thanks for the feedback, I will incorporate as much of it as I can, and post an update shortly.
Cheers,
-Eri
|
|
|
|
|
|
I have Visual Studio 6.0 loaded in my PC. However when I try to execute the 'RBDeskBand.msi' file it prompts me the [Open with..] dialog box. It looks like '.msi' is not a registered file type and no application is associated with msi extension. How should I proceed ?
Thanks Very Muc
|
|
|
|
|
You can use the Visual Studio Installer which is part of VS6, you can upgrade to Windows 2000 which has the installer built in, or you can use the full install version which will install Microsoft Installer on the machine you are using before attempting to install the RBDeskBand files. You can retrieve the Installer and package from my website. It is too large to submit to codeproject.com.
Hope this solves your problem,
-Eri
|
|
|
|
|
|
Good question. I knew something was missing from my submission. There are 3 types of deskbands. A Communications Band which sits at the bottom of an instance of IE4+. An Information Band sits on the left hand side of an instance of IE4+, like the search bar that allows you to search for files or folders on a hard drive. A Desk Band sits on the desktop, it can float or dock to any of the 4 sides of your monitor.
To see this, start IE4+. Click the "View" menu item, go down to the "Explorer Bar" menu item. The top half above the seperator are the available Information Bands, the bottom half are the communication bands.
To see a deskband, right click on the taskbar (area connected to the start button). Select the toolbar's menu item from the context menu. listed are the available deskbands.
Deskbands can also reside as toolbars inside IE4+. The wizard does not currently provide this code although I do have it available. I will be updating the wizard in the next week or so to support toolbars and be more configurable.
Hopefully this explains deskbands. I will update the article at the same time I update the wizard with this explainiation.
Thanks for the feedback,
-Erik
|
|
|
|
|