|
Hello, could someone give an example of how to place a dialog in a dll and then howto create that dialog from my MFC-app?
|
|
|
|
|
Your dll must be an MFC Extension DLL, not a normal one.
Create a new project with AppWizard and indicate MFC AppWizard(dll), then MFC Extension DLL.
your DllMain must look like this
static AFX_EXTENSION_MODULE EcamecExtDLL = { NULL, NULL };
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
// Remove this if you use lpReserved
UNREFERENCED_PARAMETER(lpReserved);
if (dwReason == DLL_PROCESS_ATTACH)
{
// Extension DLL one-time initialization
if (!AfxInitExtensionModule(EcamecExtDLL, hInstance))
return 0;
// Insert this DLL into the resource chain
// NOTE: If this Extension DLL is being implicitly linked to by
// an MFC Regular DLL (such as an ActiveX Control)
// instead of an MFC application, then you will want to
// remove this line from DllMain and put it in a separate
// function exported from this Extension DLL. The Regular DLL
// that uses this Extension DLL should then explicitly call that
// function to initialize this Extension DLL. Otherwise,
// the CDynLinkLibrary object will not be attached to the
// Regular DLL's resource chain, and serious problems will
// result.
new CDynLinkLibrary(EcamecExtDLL);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
// Terminate the library before destructors are called
AfxTermExtensionModule(EcamecExtDLL);
}
return 1; // ok
}
#endif
// MyDlgInclude.h
#ifdef _WINDLL
#include "resource.h"
#define DLL_FUNCTION __declspec(dllexport)
#else
#define DLL_FUNCTION __declspec(dllimport)
#endif
Then declare your Dialog class using one of this diferent approach
1- Export only the class metod you will use in your app
class CMyDlg : public CDialog
{
public:
MY_AFX_EXT_CLASS CMyDlg();
MY_AFX_EXT_CLASS int DoModal();
// Dialog Data
//{{AFX_DATA(CMyDlg)
enum { IDD = 100 };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMyDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CMyDlg)
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
2 - Export the whole class
class MY_AFX_EXT_CLASS CMyDlg : public CDialog
{
public:
CMyDlg();
int DoModal();
...... // same code
};
// MyApp.cpp
#include "MyDlgInclude.h"
CMyDlg nDlg;
nDlg.DoModal();
|
|
|
|
|
The *requirement* to be an extension DLL is not true at all. You can also use a regular DLL and invoke the dialog box through an exported function.
|
|
|
|
|
Hello, I have a problem reading a string from the registry (Windows CE)
I created two value's with the remote registry editor.
UserLevel:REG_DWORD:0x01
ProgUnitID:REG_SZ:696969
here's a snippet
DWORD UserLevel;
CString ProgUnitID;
//TCHAR ProgUnitID;
DWORD type;
DWORD size = sizeof(DWORD);
int result = RegOpenKeyEx(HKEY_LOCAL_MACHINE,_T("Software\\GinaII"),
NULL,KEY_ALL_ACCESS,&hKey);
if(result==ERROR_SUCCESS)
{
RegQueryValueEx(hKey,_T"(UserLevel"),NULL,&type,(BYTE*) &UserLevel,&size); // works well, function returns 0
RegQueryValueEx(hKey,_T("ProgUnitID"),NULL,&type,(BYTE *) &ProgUnitID,(DWORD*)(sizeof(TCHAR)*6)); // function returns 0
Result:
UserLevel=1
ProgUnitID={""}
What am I doing wrong here?
Arjan
|
|
|
|
|
I think your ReqQueryValueEx has failed with a error. Your parameters are wrong.
Try
TCHAR szProgUnitID[32];
DWORD dwProgSize = 32;
long lResult = RegQueryValueEx(hKey,_T("ProgUnitID"),NULL,&type,(LPBYTE) szProgUnitID,&dwProgSize);
|
|
|
|
|
try with this function
ReadString(LPCTSTR SectionName, LPCTSTR KeyName, LPTSTR Value, DWORD BufSize, LPCTSTR DefaultValue, HKEY key)
{
RegCreateKeyEx(key, SectionName, 0, NULL, 0, KEY_READ, NULL, &hkey, &KeyAction);
if (RegQueryValueEx(hkey, KeyName, NULL, NULL, (byte*)Value, &BufSize) != ERROR_SUCCESS)
_tcscpy(Value, DefaultValue);
}
ReadString(_T("software\\test"), _T("keyname"), Buffer, BufferSize, _T("Default Value"), HKEY_CURRENT_USER);
I have used this a lot under CE.
- Anders
Money talks, but all mine ever says is "Goodbye!"
|
|
|
|
|
Accepting the lack of error handling, shouldn't you use
_tcsncpy(Value, DefaultValue, BufSize); rather than
_tcscpy(Value, DefaultValue);
Gavin
|
|
|
|
|
After RegOpenKeyEx()...
Try this :
_TCAHR *ProgUnitID;
if(result==ERROR_SUCCESS)
{
DWORD dwcMaxValueData;
RegQueryInfoKey (hKey, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &dwcMaxValueData, NULL, NULL);
ProgUnitID = new _TCHAR[dwcMaxValueData] ;
RegQueryValueEx(hKey,_T"(UserLevel"),NULL,&type,(BYTE*) &UserLevel,&size); // works well, function returns 0
RegQueryValueEx(hKey,_T("ProgUnitID"),NULL,&type,(BYTE *) &ProgUnitID,(DWORD*)(sizeof(TCHAR)*6));
}
Prasanna
|
|
|
|
|
RegQueryValueEx(hKey,_T("ProgUnitID"),NULL,&type,(BYTE *) &ProgUnitID,(DWORD*)(sizeof(TCHAR)*6));
The problem is (DWORD*)(sizeof(TCHAR)*6) . That parameter is not a pointer to a DWORD variable. Reset size to sizeof(TCHAR)*6 and pass &size .
--Mike--
http://home.inreach.com/mdunn/
Trillian: What are you supposed to do with a manically depressed robot?
Marvin: You think you've got problems. What are you supposed to do if you are a manically depressed robot?
|
|
|
|
|
Hey!
I recently experienced a weird List View behavior.
I subclassed the control and then set it to Report mode. Then I wrote some code that logs WM_LBUTTONDOWN and WM_LBUTTONUP messages to a file, whenever they are received in the subclassed procedure - before forwarding it to the original control's procedure.
I noticed that when I click on an item in the control, only WM_LBUTTONDOWN is received. (When I click on other part of the client area a WM_LBUTTONUP is also received).
Why, and how does it happen?
Actually I came across all that, trying to solve some text alignment related problem. I wanted to have a right-aligned list - but the List View control doesn't support the right-align attribute of the leftmost column. So I tried doing like the documentation suggested, inserted a dummy column, then the actual column as column 1, and finally removed the dummy column. This right-aligned the items in the list, but I had to click the left part of the control to select them - as if they were on the left! So I tried to replace the LPARAM of every WM_... mouse message to a number that defines coordinates as if the user actually did click on the left part of the control. This worked fine, until I tried to catch the NM_CLICK message. The List View control didn't send it when I clicked the right part of the control, and this got me investigating... If you have any idea, please share it
Thanks!
|
|
|
|
|
List control enters modal message loop after pressing the mouse button. Here's what MSDN says:
WM_LBUTTONDOWN: Processed in different ways depending on whether a click or drag operation is being initiated. To determine which operation is involved, the list view control enters a modal message loop until either the button is released or the mouse is moved.
This means that WM_LBUTTONUP will not get through message loop of your application.
Tomasz Sowinski -- http://www.shooltz.com
|
|
|
|
|
Thank you very much!
I will now resort to MSDN to read what exactly "modal message loop" is
|
|
|
|
|
Hi,
I am using MFC(singledocument) to display some 3D physical simulation with OpenGL. My problem is that the display is really slow when my display-window is large. Does anyone have any good ideas on how to speed up the display? The graphics is really simple, (i.e not photographic).I only need 8bit colors. For the smoothness of animation I need doublebuffering, but antialiasing is already turned off. Often only small parts of the window changes between frames. Is it possible to redraw only parts of the screen? I have also tried different settings for the pixelformat, f.x lowering the colordepth etc, but that has not made any large impact. Any ideas on the topic is welcome. Thanks.
JoNy
|
|
|
|
|
Are you SURE you're finding your 3d hardware correctly?? Perhaps your app isn't initializing OpenGL correctly, and you're ending up with the software implementation??
|
|
|
|
|
Thanks,
how do I check if the application finds the 3d hardware?
/JoNy
|
|
|
|
|
I almost finished my tree view... One thing though, when I end editing a label, I have to click somewhere outside the temporary edit control that the treeview created. I want to type the label ending by pressing return. Is there a way to do this? I think I must get the temporary edit control's messages, but how? I "can" get a pointer to the temporary eidt control. One more thing, it's a plugin for 3d Studio Max, so I have to turn off accelerator keys when editing a label, otherwise max's shortcuts get performed. Maybe this is why pressing return doesn't end label editing? Thanks for your time,
WAVK
|
|
|
|
|
You don't have to explicitly handle Enter key during in-place item edit. I think 3DSMAX is interfering. Use CTreeCtrl::GetEditControl if you need to directly access in-place edit control. However, this will not help if MAX is using Enter as accelerator - the message will never reach your window.
Tomasz Sowinski -- http://www.shooltz.com
|
|
|
|
|
Thanks for your reply Few questions...
- You don't have to explicitly handle Enter key during in-place item edit.
So when someone presses Enter after editing the name, the TVN_ENDLABELEDIT message should be sent, or do I get this wrong?
- I think 3DSMAX is interfering. Use CTreeCtrl::GetEditControl if you need to
- directly access in-place edit control. However, this will not help if MAX
- is using Enter as accelerator - the message will never reach your window.
I called DisableAccelerators() so that no accelerator keys get carried out, including max's. Is Enter considered an accelerator? And if I directly access the in-place edit control, how do I catch messages for it ( if max doesn't steel them from me ). Thanks again
WAVK
|
|
|
|
|
I've a class that's not a message map(non CWnd derived) and I want to add some kind of timer(delay) in my function.
Thanks in Advance
Le Ridder Noir
Considderd to be the worlds fastest knoppenbonker.
one year of working experience with the worlds fastest copie paster(about 2000 lines a minute).
And experience with the one and only NewEra Guru and Crystal Ace.
|
|
|
|
|
If you want to just have a delay you can use sleep(). To use Windows timers without messages (and thus messagemaps) you can simply pass the address of a callback to SetTimer(). But remember, this callback cannot be a non-static member function of a class (because of the this pointer).
Cheers
Steen.
"To claim that computer games influence children is rediculous. If Pacman had influenced children born in the 80'ies we would see a lot of youngsters running around in dark rooms eating pills while listening to monotonous music"
|
|
|
|
|
In Java, you can add a static initializer to a class, which will get executed exactly once when that class is loaded. In Pascal, you can add an initialization section to a source file, which will get executed exactly once at program startup.
I would like to do something similar in C++, i.e. I want to add some code to each class or source file, which I can execute at startup without having to explicitly call it from WinMain(). The reason for this is simple: if I add an initialization block to every one of the almost 200 modules currently in my project, I will need to write 200 lines with nothing but initializeFile1(); initializeFile2(); and so on.
BTW, what I'm trying to do is to get code modules to automatically register a set of function pointers with a simple command prompt system. Is there any way I can mimic the Java or Pascal functionality in C++?
Thanks,
- Tom
|
|
|
|
|
Create a static function and call it from the constructor only if registration has not occured. You can set this up with a static bool, if it's not easy to check.
Christian
As I learn the innermost secrets of the around me, they reward me in many ways to keep quiet.
Men with pierced ears are better prepared for marriage. They've experienced pain and bought Jewellery.
|
|
|
|
|
I'm not sure what do you mean by module. You may try to create a simple struct with init code in constructor:
struct InitSomeStuff
{
InitSomeStuff()
{
}
} iss;
iss variable is a global one - it's constructor will be called before main or WinMain. In your case, you'd have many such structs, each named differently - if you need a static initializer for CFoo, name it CFoo_init or initCFoo or static_initializer_for_class_CFoo.
Note that C++ does not guarantee the order of initialization: if you'll have InitFoo, InitBar and InitBaz defined in multiple .cpp files, you can't assume that InitFoo will be called before or after InitBar.
Tomasz Sowinski -- http://www.shooltz.com
|
|
|
|
|
Thanks for the suggestions. My code is part procedural and part object-oriented, so Tomasz's suggestion seems to be the way to go.
- Tom
|
|
|
|
|
Hi all,
I apologise if this is real simple stuff, I am new to C++.
I come from a 16 yr UNIX background, so I think in script & Perl.
I am trying to check if a character in a CString is a uppercase Alpha.
if ( yousaid.GetAt(current_pos) == "[A-Z]" )
This obviously isn't how to do it in C++
Any help appreciated.
Cheers Dudes
Tryhard
|
|
|
|
|