I'm using raw Win32 and C++ for a project. As I understand it, I am able to superclass Windows controls by retrieving the class information, replacing the procedure, then registering this as a new class and using it when creating a new window. Subclassing is done by replacing the window's procedure after the window is created. The advantage of superclassing is that you are able to process messages before CreateWindow() returns.
I'm looking to see if it's possible to superclass a dialog box created with CreateDialog() because I'd like to use a resource file for the dialog layout. The problem is that I don't know how I would provide my superclass when I create a dialog box. Is it even possible? Any idea how MFC handles this?
If you use an extended dialog box template to create your dialog, you can specify a custom window class as part of the DLGTEMPLATEEX definition.
The dialog manager will create and layout your dialog as normal, and call your window procedure for any dialog messages. You can use the DefDlgProc function to obtain default processing for any dialog messages you don't want to handle yourself.
Related
I want to build a MFC application, with one main dialog, and all the other dialogs are child of this main dialog (and embedded in it).
Now, i was able to embed the first child in the main dialog, but i want to pass to the next dialog (note that the order of opened dialogs is random), so i need to hide the first dialog and show another. To know which dialog is shown at the moment and hide it, i've tried using a CDialog variable to store the current opened dialog, but i get a CObject::operator =' : cannot access private member declared in class 'CObject' error.
Is there another way to do this "hide and show dialogs" game?
EDIT: Could i store some ID of the dialogs and use it to acomplish this task?
So i managed to accomplish this task using classes IDDs.
First, i store the last opened dialog's IDD
m_dlgStartPage.Create(CStartPageDlg::IDD, this);
m_openedWin.nDialogIDD = m_dlgStartPage.IDD;
m_dlgStartPage.ShowWindow(SW_SHOW);
Then, when a new dialog needs to be shown, i send a message to my main dialog (nIDD is the IDD of pending dialog to show):
AfxGetApp()->m_pMainWnd->SendMessage(WM_COMMAND_CHANGE_WINDOW, nIDD, 0);
And last, in my main dialog, i parse all the child dialogs and check if m_openedWin.nDialogIDD matches with each dialog's IDD, so i can hide it. After this, i parse once again all the chid dialogs and use the nIDD from the sent message to show the correct one.
I don't really like this approach, because of all the parsing and sent messages to the main dialog's class, so if anyone has a better idea or method, please post it.
How do I add simple child window controls (e.g. a button) to a CWindowImpl?
I've looked at CWindowImpl and CDialogImpl. With CDialogImpl, it appears that you just create a dialog template resource and use it, very simple. I would like to do something similar with CWindowImpl, but there doesn't seem to be a way to do it. Must I add the controls manually and position them programmatically?
Some context on what I'm trying to do: I'm trying to create a plug-in for foobar2000, a Windows audio player. I would like to create a "UI element" plugin, and in the sample code that I've looked at, a "UI element" is created via CWindowImpl. How do I add buttons to this CWindowImpl? I've tried using a CDialogImpl instead, but this gives me a "pop-up" dialog, which is not what I'm looking for.
Thanks very much in advance!
With any window, including CDialogImpl, you can add child controls by creating a new window of control class and specifying your parent window handle as a parent for new control. Additionally, SetParent API is here to re-parent any window.
A MDIParent Wnd has many MDIchild Wnds, and also few child dialogs.
Dialogs are created this way ---
CAutoDlg *pDlg = new CAutoDlg;
pDlg->Create(IDD_AUTOCARD,this);
I want to cascade only a specific type of dialogs, say dialogs of CAutoDlg type only.
If i give MDICascade() it cascades all the child windows and dialogs under the MDIFrame.
Is there any other un-conventional way other than calling SetWindowPos for each dialog, based on the position of the previous dialog?
There is no direct way to do this. You can have collection of CAutoDlg into some container. Using that container call appropriate function to cascade. You may use the CAutoDlg's constructor to add dialog object into that container, and use destructor to remove dialog reference from container.
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.
I have a custom MFC control, subclassing CWnd. Other than providing OnPaint and PreSubclassWindow implementations, it overrides no default functionality and does nothing weird in construction except registering a window class in the constructor.
The control is added to the dialog using the dialog editor to add a custom control.
The dialog worked when it was a simple modal dialog deriving from CDialog, but we have code which calls CWnd::CreateDlgIndirect to instance dialogs and this fails with the custom control... but works if the custom control is removed from the resource template.
Found it!
I had the custom control register its window class in its own constructor. I had member in the dialog of this custom control type, so the ctor was being called when the dialog was created, as intended.
But, it turns out the base class I changed the dialog to derive from, instead of CDialog, was calling CreateDlgIndirect in its own ctor, before my new class' own initialisation was reached - so it was trying to create custom control before the window class was registered.
My (slightly messy solution) is to ensure the window class registration happens at application startup in the InitInstance method, before any dialog stuff happens.