|
Anonymous wrote:
I wrote a simple win32 dll (non MFC) and tried to invoke its functions using run-time Loading (LoadLibrary).
This does not indicate that two DLLS are being used. I presume this is not the case and that there are actually two DLLS, one MFC and the other non-MFC. Yes?
Are the exported functions written in C++? If so, it sounds like name-mangling is at work here.
|
|
|
|
|
bad answer greg!!!
i assume u defined your function like this:
void __declspec( dllexport ) foo()
{
...
}
this causes c++ name convention when using a c++ compiler!
to get a c export(which u want), use:
extern "C" void __declspec( dllexport ) foo()
{
...
}
Don't try it, just do it!
|
|
|
|
|
10x
Another question: is there any way to use a class defined and exported from a dll loaded by LoadLibrary() ?
Its if you can explain what is a "name convention" it would be grate
thanks.
|
|
|
|
|
i askey myself this question many times, it is possible, the half-life engine does it, but i still dont know how...
Don't try it, just do it!
|
|
|
|
|
Yes there is..
In fact, I pondered over this same problem a while back. The idea was that I was supposed to use a class which is completely declared inside a DLL. I only had the header files for reference.
So, here we go, first the actual class, declared with typedef. Do this in a seperate header file:
[code]
typedef class {
public:
// Some initialization functions ?
virtual HRESULT InitModule(void);
virtual HRESULT QuitModule(void);
// A member variable perhaps ?
int iMemberVariable;
} MyExportedClassType;
// Pointer-to-function returning address-of WindowPlugin class
typedef MyExportedClassType* (*GetClass)(void);
[/code]
What ? A pointer-to-function blablabla ? What's that ?
Simple: That is the key to this whole mess: a pointer to a function. Why is it declared there ? Because the same header file is used in the loading application. Just for the sake of simplicity.
Now, when we have the actual class, let's see the DLL exporting it:
[code]
// On global level, declare an instance of the class
MyExportedClassType MyClass;
// At the DllMain, initialize the class' members
int WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpVoid)
{
.... Some code here
MyClass.iMemberVariable = 10;
.... More code here
return TRUE
}
// Add an exported function, which returns the address of our class
__declspec(dllexport) MyExportedClassType* ProvideAddressOfClass(void)
{
return &MyClass;
}
[/code]
Lastly, create a module definition file
[code]
LIBRARY
EXPORTS
ProvideAddressOfClass @1
[/code]
Ok, now the DLL is ready, go compile it. Next up, the loading application:
[code]
// We must include the typedef declaration
#include "myclasstypedef.h"
HDLL hDll;
// See here: let's create a pointer-to-function which returns a class' address.. Remember, we exported this type of function from the DLL !
GetClass MyClassProvider;
// A pointer to our class type
MyExportedClassType* lpImportedClass;
// Your main function
int main(void)
{
.... Some code ?
// Load module
hDll = LoadLibrary(ModuleName[iCount]);
// Resolve address of exported function
MyClassProvider = (GetClass)GetProcAddress(hDLL, "ProvideAddress");
// Get address of class within the DLL, using the exported function
lpImportedClass = MyClassProvider();
// Let's use it !
lpImportedClass->iMemberVariable = 1;
.... Some more code
// Remember to unload the library !
UnloadLibrary(hDll);
// End application
return 0;
}
[/code]
Seems difficult ? Well, it really isn't.. To sum it all up programmer-wise:
1. Create a class using typedef
2. Create a function which returns the address of your class
3. Export this function in the DLL with __declspec AND .def file
4. Create a typedef for 'pointer-to-function' of the address-provider function
5. Load the DLL in another application
6. Get the address of the exported function
7. Use the function to get the address of the class
8. Use the class
9. NULLify pointers, unload the DLL etc clean-up work
10. Quit and get some sleep
I have created an example of this, an application which actually creates it's main window in a seperate DLL, and adds event handlers to this window's procedure in another DLL. You can download the entire workspace (3 projects: WinDLL, InpDLL, WinLoader) from here.
Enjoy !
-Antti
|
|
|
|
|
[EDIT]I'm using VS6[/EDIT]
This is an obscure problem: I'm using an edit control labeled IDC_EDIT2 in a dialog-based app. To restrict the length of the content to 8, I use the following function that is called whenever the content changes:
void CFileCryptDlg::OnChangeEdit2()
{
char strPassword[10];
if(GetDlgItemText(IDC_EDIT2,strPassword,10)>8)
{
strPassword[8]='\0';
SetDlgItemText(IDC_EDIT2,strPassword);
}
}
It works fine, except for one small problem: till I type the 8th character, everything's as expected. But when the 9th character is typed, the cursor moves back to the first location in the edit box. How do I retain the cursor position?
Thanks,
Vikram.
The use of COBOL cripples the mind; its teaching should, therefore, be regarded as a criminal offence.- Dijkstra
KI klike KDE kand kuse kit, kbut KI kmust kadmit, kstarting kall knames kwith K kis ksilly. KI khope kthey kwill kgive kup kthis kwhole kscheme ksoon kand kcome kup kwith kreal knames.
pI vThink aHungarian nNotation vIs iA aWonderful nThing cAnd pEveryone avShould vUse pIt aAll dThe nTime, adNo nMatter pWhat dThe nContext, adEven adWhen vSpeaking.
|
|
|
|
|
Why don't you just do SendMessage(wndOfYourEdit, EM_EXLIMITTEXT, 8, 0); ?
This will limit the edit control to accept max. 8 chars.
regards
modified 12-Sep-18 21:01pm.
|
|
|
|
|
I tried what David said below and it works.
On a purely academic note, how come neither
::SendMessage(((CEdit *)GetDlgItem(IDC_EDIT2))->m_hWnd, EM_EXLIMITTEXT, 8, 0);
nor
GetDlgItem(IDC_EDIT2)->SendMessage(EM_EXLIMITTEXT, 8, 0);
works when called from the dialog's InitInstance() function? They don't restrict the number of characters at all.
Cheers,
Vikram.
The use of COBOL cripples the mind; its teaching should, therefore, be regarded as a criminal offence.- Dijkstra
KI klike KDE kand kuse kit, kbut KI kmust kadmit, kstarting kall knames kwith K kis ksilly. KI khope kthey kwill kgive kup kthis kwhole kscheme ksoon kand kcome kup kwith kreal knames.
pI vThink aHungarian nNotation vIs iA aWonderful nThing cAnd pEveryone avShould vUse pIt aAll dThe nTime, adNo nMatter pWhat dThe nContext, adEven adWhen vSpeaking.
|
|
|
|
|
Probably because a dialog does not have such a method. Are you talking about OnInitDialog() ? Either way, the EM_EXLIMITTEXT message is for rich edit controls.
|
|
|
|
|
Is your edit control already created in InitInstance()? I'd prefer OnInitDialog().
modified 12-Sep-18 21:01pm.
|
|
|
|
|
Why not just use SetLimitText(8) ?
|
|
|
|
|
Works!
Thanks a zillion !
Regards,
Vikram.
The use of COBOL cripples the mind; its teaching should, therefore, be regarded as a criminal offence.- Dijkstra
KI klike KDE kand kuse kit, kbut KI kmust kadmit, kstarting kall knames kwith K kis ksilly. KI khope kthey kwill kgive kup kthis kwhole kscheme ksoon kand kcome kup kwith kreal knames.
pI vThink aHungarian nNotation vIs iA aWonderful nThing cAnd pEveryone avShould vUse pIt aAll dThe nTime, adNo nMatter pWhat dThe nContext, adEven adWhen vSpeaking.
|
|
|
|
|
COleSafeArray::PutElement
Does this function append to the array ?
|
|
|
|
|
Nope. I can say this caregorically, since it's a wrapper around the SafeArrayPutElement function, and that doesn't.
Use the source, Luke
Steve S
|
|
|
|
|
This should be a simple question, but how do you create a CRichEditCtrl for version 2.0/3.0 using either Create or CreateEx?
Larry J. Siddens
Cornerstone Communications
TAME THE DOCUMENT MONSTER
www.unifier.biz
|
|
|
|
|
What specifically is not working for you? If the control's parent is a dialog, add a control variable to the dialog's .H file, and then in the dialog's OnInitDialog() method, add:
AfxInitRichEdit();<br />
richedit.Create(...);
|
|
|
|
|
Might be that they're wanting specifically to create a richedit with Word-style paragraph formatting (left, centre, right, align). The default MFC way means that an old style rich edit is created all the time. In some cases, the way I've done this is in OnInitDialog to get the old one's attributes, trash it and recreate the control in place, before calling the default OnInitDialog in case that maps a control.
There are two Windows class names, "RichEdit" which is v1.0 and RICHEDIT_CLASS which expands at compile time to produce the appropriate name for v2 or later.
Steve S
|
|
|
|
|
The AfxInitRichEdit() loads the RICHED32.DLL with is version 1.0. I want to load 2.0/3.0
Thanks
Larry J. Siddens
Cornerstone Communications
TAME THE DOCUMENT MONSTER
www.unifier.biz
|
|
|
|
|
My bad. When I saw richedit32, I just assumed v3.2, not 1.0. You have to go to richedit20 in order to get v3.0. Are we confused yet?
So, the moral to your story is that the CRichEditCtrl class does not support the Rich Edit v2.0 control. In order to use Rich Edit 2.0 in an MFC application, call LoadLibrary() to load the Riched20.dll and access its functionality through the Win32 API. Hmmm
|
|
|
|
|
So you use the LoadLibrary to load the riched20.dll and use the handle to set the fonts, formating, . . . Correct?
Can you place a small example. I have not called items from the library.
Thanks
Larry J. Siddens
Cornerstone Communications
TAME THE DOCUMENT MONSTER
www.unifier.biz
|
|
|
|
|
HMODULE hLibrary = LoadLibrary("riched20.dll");<br />
<br />
m_richedit = CreateWindowEx(0, RICHEDIT_CLASS, "", WS_CHILD | WS_VISIBLE | ES_MULTILINE, 5, 50, 100, 100, GetSafeHwnd(), NULL, NULL, NULL);<br />
<br />
::SendMessage(m_richedit, WM_PASTE, 0, 0);
|
|
|
|
|
You are loading the library to check if the riched20.dll is there correct? Now I have one more question. Have you been able to print that area correctly? If so, how? I'm trying to do that. The problem is that we don't know what the output device will be at the time of creation. Interesting twist huh?
Thanks again.
Larry J. Siddens
Cornerstone Communications
TAME THE DOCUMENT MONSTER
www.unifier.biz
|
|
|
|
|
Use EM_SETTARGETDEVICE to set the target device. Then use EM_FORMATRANGE and EM_DISPLAYBAND to display the control's contents. See the MSDN article Q129860.
|
|
|
|
|
Thats the caveat Dave, we don't know what the device is when the use uses it! What I'm currently doing is pulling each line out, scanning for font differences and using the TextOut to draw the text. Problem is that the font that shows up on the screen (fitting inside of a box) is either bigger or smaller than what was on the screen.
Kind of an interesting puzzle huh?
Larry J. Siddens
Cornerstone Communications
TAME THE DOCUMENT MONSTER
www.unifier.biz
|
|
|
|
|
Ok, I'm a tad confused at this point. Are you wanting to take text from a rich edit control and send it to a printer? It sounds like you need to use GetDeviceCaps() to make sure the target device is setup like the rich edit control.
|
|
|
|
|