|
I think you mentioned that you already tried forward declarations, and that they didn't help.
You might try putting the following line in your .h file:
#pragma once
Otherwise, try playing with #ifndef using the (very long) names #define'd by the class wizard:
#ifndef MYDIALOG_AFX_LOTSA_STUFF_THAT_LOOKS_LIKE_A_GUID
#include "mydialog.h"
#endif
|
|
|
|
|
Did you try prototyping ?
Before you use a class into an other class you have to #include the header. If you only need a pointer to an other object, you can prototype this class. The compile knows the definition (pointer to a class) and the implementation is linked afterwards.
Wimel
-objectA.h-
class objectA;
class objectB
{
objectA* m_poA;
}
-objectB.h-
class objectB;
class objectA
{
objectB* m_poB;
}
|
|
|
|
|
Hi!
I have created an Application launcher and I use CreateProcess() to launch my Apps. My problem is that I cannot close my application launcher if my applications are not finished. Is there a way to make the Application launcher and the App independent so that can close my launcher after I have created my Apps?
Everything's beautiful if you look at it long enough...
|
|
|
|
|
I founded!
Just use ShellExecute( NULL,
"open",
m_Process,
NULL,
m_Path,
SW_SHOWNORMAL
);
Everything's beautiful if you look at it long enough...
|
|
|
|
|
Instead of using CreateProcess(), maybe you should use ShellExecute to launch your other applications.
CString filepath = "C:\\temp.exe";<br />
<br />
HINSTANCE err = ShellExecute(NULL, _T("open"), filepath , NULL, NULL, SW_SHOW);
It should look something like that, but my C++ has been getting a little rusty lately.
Hope that helps.
Daniel E. Blanchard
|
|
|
|
|
My mistake, you beat me to it.
Daniel E. Blanchard
|
|
|
|
|
Yes.
Try this:
// Run specified 32-bit process
bLaunched = ::CreateProcess(
pszPath, // name of executable module
szCommandLine, // program command line
NULL,
NULL,
FALSE,
CREATE_DEFAULT_ERROR_MODE | NORMAL_PRIORITY_CLASS,
NULL,
NULL,
&si,
&pi
);
ShellExecute uses CreateProcess anyway, so you are just missing something or have a bad argument to the function.
C++/MFC/InstallShield since 1993
|
|
|
|
|
Hi there,
According to "Using a Doc/View exported from a dynamically loaded DLL (SDI)" article : http://www.codeproject.com/docview/SdiCViewDll.asp[^], I load Form Views from DLLs. Unfortunately, the View loading fails when the exported view contains Custom Controls and advanced controls such calendar, Rich Edit and so on.
Any idea ? Please help me
Thanks !!
|
|
|
|
|
Have you tried InitCommonControls[Ex], AfxInitRichEdit[2]?
Regards,
BB
|
|
|
|
|
Thank you for your answer BB, your advice is all right with rich edit control (with the use of AfxInitRichEdit), but the exported form view is still crashing with custom controls
An assert occurs on the view creation -> hWnd is NULL in CreateDlgIndirect(). I guess that something is not properly initialized but what ? That is the question, hopping that someone could answer to it...
After some searches, I didn't found anything interesting about such initialisation...
|
|
|
|
|
Following the initialization path, did you register your custom control classes in the DLL?
Regards,
BB
|
|
|
|
|
Effectively I didn't registered it. Since this custom control works when used in the main application, I was guessing that it would dirctly run.
I'm not very close to DLLs, can you quickly explain me how to register it and why it's needed ?
Thank you very much BB, I begin to see the light at the end of the tunnel
|
|
|
|
|
There's an important issue here: MFC extension DLLs maintain their own resource handle.
Personally I call such function in the C++ constructor of all my custom controls (I modified it slightly to fit your question):
BOOL CMyCustomCtrl::RegisterClass()<br />
{<br />
WNDCLASS wndcls;<br />
HINSTANCE hInst = AfxGetResourceHandle();<br />
<br />
if(!(GetClassInfo(hInst, "MyWndClassName", &wndcls)))<br />
{<br />
wndcls.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;<br />
wndcls.lpfnWndProc = ::DefWindowProc;<br />
wndcls.cbClsExtra = wndcls.cbWndExtra = 0;<br />
wndcls.hInstance = hInst;<br />
wndcls.hIcon = NULL;<br />
wndcls.hCursor = LoadCursor(NULL, IDC_ARROW);<br />
wndcls.hbrBackground = NULL;<br />
wndcls.lpszMenuName = NULL;<br />
wndcls.lpszClassName = "MyWndClassName";<br />
<br />
if(!AfxRegisterClass(&wndcls))<br />
{<br />
AfxThrowResourceException();<br />
return FALSE;<br />
}<br />
}<br />
return TRUE;<br />
}
The function checks whether the control is registered with current resource handle, and registers it if not yet done. This way we cover both the application and DLL case. The function can be universal if you derive your custom controls from the common base class and use "MyWndClassName" as a function argument.
You may read in the MSDN what the several WNDCLASS members mean, and the code is self-commenting I guess. I hope I didn't miss anything in this explanation, but ask if there's turn out wrong.
Regards,
BB
|
|
|
|
|
Thank you BB you're great, I'll try this as soon as possible and I'll post the result here in order to let users and you know if it works.
Thank you again !
|
|
|
|
|
Dear BB,
Your solution doesn't work for the moment. After some debug, it appears that the Form View window handle is not valid. According to http://www.cpp.atfreeweb.com/MFC/LoadFrame/Index.asp[^], AfxHookWindowCreate() does the following things :
- CFrameWnd::OnCreate
- Calls CWnd::OnCreate
- Calls OnCreateClient, which, if a context with a new view class is supplied, calls CreateView (and that is where the view is created) with the context and an id of AFX_IDW_PANE_FIRST
- Sends (using PostMessage) a WM_SETMESSAGESTRING message to set the status bar message to the string with a resource id of AFX_IDS_IDLEMESSAGE
- Calls RecalcLayout
I'm sure the problem cames from CWnd::OnCreate but I don't know why it return a NULL window handle...
|
|
|
|
|
When you are to create the form view, set the resource handle to the DLL one. These are the steps required (file and variable names assumed, use your own):
1. Near the DllMain function in YourDllName.cpp, find a declaration like: AFX_EXTENSION_MODULE YourDLL = { NULL, NULL };
2. In YourDllName.h (if it doesn't exist, create it), declare:
extern AFX_EXTENSION_MODULE YourDLL;
3. Before form creation, set the handle:
HINSTANCE hPrevHandle = AfxGetResourceHandle();<br />
AfxSetResourceHandle(YourDLL);
// TODO: create view here
AfxSetResourceHandle(hPrevHandle);
If the handle is not set to a module where you defined a dialog template, it cannot be loaded and thus creation fails.
Additionally, you may use a class that encapsulates above functionality and restores the original handle in its destructor (when going out of scope):
class CResourceHandler<br />
{<br />
public:<br />
HINSTANCE m_prevHandle;<br />
<br />
public:<br />
CResourceHandler(AFX_EXTENSION_MODULE &module);<br />
{<br />
m_prevHandle = AfxGetResourceHandle()<br />
AfxSetResourceHandle(module.hModule);<br />
}<br />
<br />
CResourceHandler(HINSTANCE &handle)<br />
{<br />
m_prevHandle = AfxGetResourceHandle();<br />
AfxSetResourceHandle(handle);<br />
}<br />
<br />
virtual ~CResourceHandler()<br />
{<br />
AfxSetResourceHandle(m_prevHandle);<br />
}<br />
};
4. With the class, the creation code simplifies as follows:
<br />
void CreateMyFormView()<br />
{<br />
CResourceHandler rh(YourDLL.hModule);
// TODO: create view here
}
Of course, the CreateMyFormView() function has to be located in a DLL.
Regards,
BB
|
|
|
|
|
Hi,
I have a problem. I have to read the name of a class in a data base and then try to instanciate a object of that class. How can i do it?
Example:
CString className = "CMyClass";
CRuntimeClass* ptr = RUNTIME_CLASS(class); -> Error
CObject* o = ptr->CreateObject()
|
|
|
|
|
Use a class factory to instantiate the class, given its name.
/ravi
Let's put "civil" back in "civilization"
http://www.ravib.com
ravib@ravib.com
|
|
|
|
|
|
I have a dialog application and would like to have a menu selection up in the title bar pull down menu for an "about" box. How do I add this?
My dialog has the following options selected:
Popup
Thin
title bar
system menu
Thanks for the help
|
|
|
|
|
Add this code in your dialog's OnInitDialog() handler:
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
IDM_ABOUTBOX is a string resource with the value "About MyApp..."
/ravi
Let's put "civil" back in "civilization"
http://www.ravib.com
ravib@ravib.com
|
|
|
|
|
I just figured this was missing by doing a compare.
Now I just have to get it to call the dialog I want.
Thanks for the timely responce.
Jim
|
|
|
|
|
Thought I had this wipped, but I can't seem to intercept the OnSystemCommand.
How does the drop down menu on the system title bar get called and where is it located?
It's like it just magically does it on its own.
|
|
|
|
|
Hi All,
I was wondering what would be the difference and why would I want to use either type. The application wizard let's me make a standard dll using mfc shared/static or an MFC extension dll.
Any clarification would be helpfull.
Cheers,
Clint
|
|
|
|
|