1.i have derived a class from CStatic called CLed_arr.
2.a cstatic control named IDC_leds was added to the dialog window in resource editor.
3.a member var called m_led_arr of the class CLed_arr was created for this IDC_leds.
4.the class CLed_arr contains an array Led[16] of objects of class CLed.
5.the class CLed itself is derived from CStatic.
6.i did'nt want to put these 16 led windows in resource editor,but wanted to create them at run time.for creation of these 16 windows the co-ordinates of the mother window i.e.IDC_leds are required.i tried the creation process in the CLed_arr constructor.but probably at this instant the window of the class is not available so i get exception.so i wanted to do it using some message handler using the creation the window message of this class i.e. CLed_arr.but the only message available for this class is BN_CLICKED.
7.pls help me in understanding as to why only BN_CLICKED message is available for this window,also what is the method if any available for adding additional messages for this window.
8.i'm able to create these 16 windows if i create them in OnitDialog(),but i want to develop this CLed_arr as a class whose basic procedures are within the class.
pls. hlp.
thnx
In MFC CWnd is the base class for most of the UI classes, for CStatic as well ofcourse.
So try handling WM_CREATE msg from CWnd. It will come once the window is created but just before it gets visible. For more information see here
Related
I am using Visual Studio 2019 and building a C++ desktop application. I have a dialog class inherited from CDialogEx. In this class I have a few buttons, i.e. CButton as members.
When I use the EnableWindow method in the class constructor, it reports:
Debug Assertion Failed! Program C:\WINDOWS\SYSTEM32\mfc140ud.dll File:
d....\winocc.cpp line 345
If I commented it out the application worked fine. Any idea why I have this error? All I wanted to do is to disable the buttons as soon as the dialog shows up - that is why I use this method in the constructor.
There is a difference between a C++ class and the actual creation of the dialog window and its controls.
The constructor is for class related items, not window related items. For example, if you want to initialize member variables, then the constructor would be the place for it. But at construction, no dialog window has been created, thus there are no child controls that exist, thus the error you're seeing.
The place where you can assume that the window is created is in the dialog's OnInitDialog member function. This is where you should be able to call EnableWindow on the controls.
If you do not have an OnInitDialog, you can add that function using the class wizard.
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.
I am looking at some MFC/C++ CView object subclass like this:
BOOL CCustomView::CreateView(DWORD dwStyle,
CDocument * pDocument,
CWnd * pParent,
String title)
{
...
CString className = AfxRegisterWndClass(CS_DBLCLKS,
::LoadCursor(NULL, IDC_IBEAM));
return Create(className, title, dwStyle,
rect, pParent, -1, &context);
}
What I don't like about this, although maybe it's normal for MFC application programming, is that the runtime Window Class Name, is not a name of my own choosing. If later, I wanted to find this window, from another Win32 application, and find the window by window class name, I'd have to use the ugly "Afx:123:39843:39843" strings, and actually, I don't know if those window class names can be counted on to not change. I'd rather change the window class to "CCustomView", but still have it have the same behaviours as the window class created above. How do I do that?
There are better ways to solve your problem. The typical protocol I use is:
Register a window message using RegisterWindowMessage in both applications. The message name should contain a GUID to make it unique
In Application A, use
PostMessage(HWND_BROADCAST, registeredMsg, idIWantToFindYou, HWNDofA)
to publish your window handle to all top level windows. since there's more than one use for registered messages, and you should limit the number of messages you register, use idIWantTofindYou to distinguish between different commands for your message.
The receiving application(s) B now have the window handle of the sender, and can establish a connection (e.g. by
PostMessage(HWNDofA, registeredMessage, idHereIsMyHWnd, HWNDofB)
The upside of this mechanism is not running into problems with unresponsive programs. However, the "connection" isn't immediate, so you have to change your program flow. Alternatively, you can use EnumWindows and SendMessageTimeout to probe all top-level windows.
If you need to use the window class:
The class name assigned by MFC is only so window classes with the same attributes get reused. I am not aware of any problems with using your own window classes.
So the following should work:
Fill a WNDCLASS or WNDCLASSEX with the required attributes
Use DefWindowProc as WNDPROC (that's what MFC does, MFC's WNDPROC is set when creating the window)
Use AfxRegisterClass or RegisterClass to register the window class. AfxRegisterClass checks if the class is already registered and if the class is registered from a DLL, it will unregister the class when the DLL is unloaded. Otherwise they are roughly equivalent.
I'm writing a custom control derived from CWnd. I want to initialize a member variable (e.g: a memory dc) of my custom control class using its device context. Which is the correct way to do it? I guess device context won't be ready in the constructor. So what is the next option. Is it safe using the dc the OnCreate event? I'm probably in search of something like OnInitDialog, but its a custom control, not a dialog.
Update: I added the custom control to the parent dialog via resource editor. So there is no chance for getting WM_CREATE event as it has already been created before subclassing.
Device context can be created in OnCreate (WM_CREATE), after you call the base class' OnCreate method.
http://msdn.microsoft.com/en-us/library/dd318297(v=vs.85).aspx
From Programming Windows
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.