Extend Windows explorer with BHO - c++

I am trying to extend whindows explorer (NOT IE) with a customized panel in C++, which should look like this:
and here's a similar question I found (in C#) :
Similar question
The question is of C# and already got an answer.
But I myself find the answer is a bit too brief for me to follow, here's what I got:
I should implement a BHO object
the BHO object should implemet IObjectWithSite and IDockingWindow
In SetSite method, call QueryInterface to get the pointer of service provider, then call QueryService to get the pointer of a Docking window frame, then finally call AddToolBar to add my customized window. and here's where I got lost
and my questions are:
at what time should I create my customized window? during the initialization of the object?
I think I should get a parent window's handle (in my case I think it should be the windows explorer's handle) before I can create my own window which will be a child of it, where can I get this handle? with the pointer of docking window frame ?
How should I register my dll? I read some sample codes of preview handlers, we have to register the dll properly before it can be invoked by the system right?
I've tried to reproduce what the similar question said for days, but no luck by now.
I'm really new to BHO and all such stuff, kindly please help me out of this, thanks.

For such Explorer extension I create 2 object. First implements BHO (IDispatch and IObjectWithSite). Second implements IObjectWithSite, IOleWindow, IDockingWindow, IInputObject and IOleCommandTarget.
1) The logic of showing of your window depends on what you want to realize.
2) Parent window you can get inside Second.SetSite:
Site.QueryInterface(IDockingWindowSite, FDockingWindowSite);
FDockingWindowSite.GetWindow(FParent);
3) Just register your BHO as standard BHO.
It took a LONG time for me to create and debug such extension. If you are not expert in this sphere think again - do you really need this functionality. But if you really decided you need then try to create and register simple BHO first. And only when BHO works correctly add IDockingWindow implementation.

Related

Creating a DialogBar with MFC with my own controls

I'm turning mad with a little problem with Visual Studio 2008 and MFC. I'm working on a project actually and I'm trying to create an SDI Application. Right, now I want to add a dockable DialogBar. Well, the first time I added it with the resource view, I could create the bar without problems.
But... I want to add some controls like a couple of ListBox, buttons and so on. The program doesn't allows me to create member variables for these controls. The option appears in grey.
Searching a little, I found that it's mandatory to create a new class derived from CDialogBar and "enhance" it with the Message handler and so on. I've been reading some tutorials and it didn't work for me.
Can you please help me? I'm starting to get nervous, the use of dialogbars is mandatory in my design and I've never implemented them before.
Thank you very much, and sorry for my poor english.
You can add a control member variable by hand instead of using the wizard. All it takes is a call to DDX_Control in the dialog bar's DoDataExchange function.
But CDialogBar-derived classes do not handle control clicks. The CDialogBar class forwards all of those messages to the dialog bar's parent window. So be prepared to add the message handlers to the parent (usually CMainFrame).
For learning purposes you might try creating your dialog bar as a CDialog first, to see the proper code lines and message map entries supplied by the wizard. Then you can copy/move these details as appropriate into your actual code project.

How to hide/collapse main menu in a win32/mfc application

I always been interested on how we can accomplish this (hide/show the main menu using the alt key), and now some applications do this very often. One that really please me is the visual studio 2010 with this plugin:
http://visualstudiogallery.msdn.microsoft.com/bdbcffca-32a6-4034-8e89-c31b86ad4813?SRC=VSIDE
(firefox also do this, but i think that is in a different way)
Can anyone explain me how this can be achieved or if you known of any sample project that demonstrate this please tell me.
(what i can see in some replies here in stack is that we have to destroy the menu when is to hide and create it when is to show?! but this seems a bit bad solution...)
Thanks
The SetMenu function lets you add/remove the menu from the window. It does not destroy the menu.
Note that most applications which have the dynamic menu hide/show behavior are not really showing a menu. They're showing a custom control that looks like a menu.
You might also take a look at MFC support for auto hiding menus. I used this technique and it worked really well.
in CMainFrame::OnCreate I did
m_wndMenuBar.ShowWindow(SW_HIDE);
which actually works fine in our project
I stumbled across a related pit fall that will show a hidden main frame without your consent:
Whenever the focus for a child window in an MDI application changes (e.g. due to right clicking in it), the function CMDIChildWnd::OnMDIActivate will be called, which in turn shows the main menu (even if it was removed or destroyed previously) of the MDI application.
This works basically by adding the saved main manu from the underlying's CMDIChildWnd m_hMenuShared variable.
A quick&dirty hack to prevent this, is setting m_hMenuShared to NULL (it's protected in CMDIChildWnd so this needs a custom derived child class of CMDIChildWnd) for all child frames.

Multi-page application in Silverlight for Windows Embedded 7

I'm trying to develop an application in Silverlight for Windows Embedded 7, which uses C++.
I was able to run a simple page with a button, which calls another function (a simple Hello world message box).
The great question here is: how can I make a function display another page, defined in another XAML file? All the examples I found online, and even in Microsoft resources, uses a single XAML file with everything done inside it.
Thanks in advance!
I'm a student who is suffering from the same problem now. Hope there's someone to help us solve it.
I have searched and found that FRAME is not supported in the SWE.
I have found an alternative way to solve this problem but I'm not familiar with C++ code.
If you knows how to program in C++, would you please read through this and teach me a bit?
Thanks so much.
You can search for"Create a Custom User Control in Silverlight for Windows Embedded".
You'll found a PDF file released by Microsoft.
With this way you can create a custom user control to hold your "multi page".
I have done this step, and with the control I created, I am able to "hide" and "show" it in order to achieve the "multipage" effect.
In my User Control, I have some more buttons to let users to click. However, from the mainpage which hosting the user control, the buttons inside cannot be detect.
In the PDF tutorial they teach how do we call out the methods in the custom control, but I don't understand the C++ code.
If you can get the user control done make the controls in your custom control function correctly, would you please tell me? thank you.
To do multi-page applications, you need multiple xaml files. Not sure what the Microsoft tutorials you found were referencing, but i am developing an application now which has more than 20 different pages or screens. You need to design the layouts in XAML/ExpressionBlend and then using event handlers and pointers to the XAMl, implement the views in the C++ source code.
// ============================================================================
// LockDataLogger_Click
//
// Description: Event handler implementation
//
// Parameters: pSender - The dependency object that raised the click event.
// pArgs - Event specific arguments.
// ============================================================================
HRESULT MainPage::LockDataLogger_Click (IXRDependencyObject* pSender, XRMouseButtonEventArgs* pArgs)
{
HRESULT hr = E_NOTIMPL;
if ((NULL == pSender) || (NULL == pArgs))
{
hr = E_INVALIDARG;
}
//m_pDeviceSettings_Lang->m_pYear->Focus(false);
if(m_pDeviceSettings_Lang)
{
m_pDeviceSettings_Lang->m_pYear->SetIsDropDownOpen(false);
}
m_pLoginScreen->SetVisibility(XRVisibility_Visible);
m_pLogin_Password->SetPassword(L"");
m_pHome_LoginOptions->SetVisibility(XRVisibility_Collapsed);
return hr;
}
So this is an event handler implementation for when you clock the "Lock" button on the home screen of my device. All you need to do is name your different pages/menus accordingly and based on event handler implementations, using points, set/change the visibility of the different pages. Very straightforward and hope the example code provides some insight.

How to create and add a custom made component to a Dialog based app (MFC)?

I want to make a custom made component (a line chart), that would be used in other applications.
I don't know 2 things:
Where should I use (within component class!) the methods for drawing, like FillRect
or PolyLine? In OnPaint handler that I should define and map it in MESSAGE MAP? Will
it (OnPaint handler) be called from OnPaint handler of the dialog of the application
or where from?
How to connect the component, once it is made, to the test application, which will
for example be dialog based? Where should I instantiate that component? From an
OnCreate method of the MyAppDialog.cpp?
I started coding in MFC few days ago and I'm so confused about it.
Thanks in advance,
Cheers.
Painting the control is handled exactly like it would be if it wasn't a control. Given that you're using MFC, that (at least normally) means you do the drawing in the View class' OnDraw (MFC normally handles OnPaint internally, so you rarely touch it).
Inserting the resulting ActiveX control in the host application will be done like inserting any other ActiveX control. Assuming you're doing your development in Visual Studio, you'll normally do that by opening the dialog, right clicking inside the dialog box, and clicking "Insert ActiveX Control..." in the menu that pops up. Pick your control from the list, and it'll generate a wrapper class for the control and code to create an object of that class as needed. From the viewpoint of the dialog code, it's just there, and you can use it about like any other control.
For create new component in MFC, you must create a class from the window class (CWND),
after that you can have your MessageMap for the component and your methods and also can override CWND::OnDraw method to draw the thing you want.
Before that I suggest you to take a look to device context
http://msdn.microsoft.com/en-us/library/azz5wt61(VS.80).aspx
Good Luck friend.

How to mix C++ and external buttons on seperate window?

I want to make a C++ button on Start>Run i.e but when I do it will not do signalled event?
Im sorry I have seen that you do not get the question.
Ok basically when you create a button with CreateWindowEx(); I want to do that but put on a different window with SetPArent which I have already done now the button does not work so I need my program to someone get when it is clicked from the Run window as example!
And yes you have it, but it's not making the button is the problem it's getting when it's clicked with my program since it does not belong to it anymore!
You need to apply the ancient but still-supported technique known in Windows as subclassing; it is well explained here (15-years-old article, but still quite valid;-). As this article puts it,
Subclassing is a technique that allows
an application to intercept messages
destined for another window. An
application can augment, monitor, or
modify the default behavior of a
window by intercepting messages meant
for another window.
You'll want "instance subclassing", since you're interested only in a single window (either your new button, or, the one you've SetParented your new button to); if you decide to subclass a window belonging to another process, you'll also need to use the injection techniques explained in the article, such as, injecting your DLL into system processes and watching over events with a WH_CBT hook, and the like. But I think you could keep the button in your own process even though you're SetParenting it to a window belonging to a different process, in which case you can do your instance subclassing entirely within your own process, which is much simpler if feasible.
"Superclassing" is an alternative to "subclassing", also explained in the article, but doesn't seem to offer that many advantages when compared to instance subclassing (though it may compared with global subclassing... but, that's not what you need here anyway).
You'll find other interesting articles on such topics here, here, and here (developing a big, rich C++ library for subclassing -- but, also showing a simpler approach based on hooks which you might prefer). Each article has a pretty difference stance and code examples, so I think that having many to look at may help you find the right mindset and code for your specific needs!
OK, I'll do my very best - as I understand you, you're trying to inject a button into some existing window. That meaning: Your tool creates a button in some window that does not belong to your application. Now, you want to be notified when that button is pressed. Am I correct so far?
To be notified about the button being pressed, you need to get the respective window message, which will only work if you also "inject" a different WndProc into the window. Actually I have no idea how that should work, but I faintly remember functions like GetWindowLong and SetWindowLong. Maybe they will help?
EDIT
I've searched MSDN a little: While you can get the address of a window's WndProc using GetWindowLong, you can not set the WndProc using SetWindowLong on Windows NT/2000/XP (and up I suppose). See here (MSDN).
So what you could do is install a global message hook that intercepts all window messages, filter those for the window you've injected the button into and then find your message. If you have trouble with this, however, I'm the wrong person to ask, because it's been years ago since I've done anything like that, but it would be stuff for a new question.
EDIT 2
Please see Alex Martinellis answer for how to define the hook. I think he's describing the technique I was referring to when I talked about defining global message hooks to intercept the window messages for the window you injected your button into.