|
Dear all, I found the solution and I like to share it with you.
I took the idea from an article I have found on your site,
http://www.codeproject.com/cpp/cppforumfaq.asp#ui_workerthread
I implemented this code within the button handler and... wonder!, it works.
OnButtonClicked()
{
m_crtlButton->Enable(FALSE);
while (Do_A_Bit_Of_Work())
{
MSG msk;
while(PeekMessage(&msg, NULL, NULL, PM_NOREMOVE)
{
AfxGetApp()->PumpMessage();
}
}
m_crtlButton->Enable(TRUE);
return;
}
Ciao and thanks for your kind help.
Daniele
|
|
|
|
|
Hi,
why don't u check LockWindowUpdate() and unLockWindowUpdate().
Lokesh
|
|
|
|
|
I'm sorry, it desn't work.
Ciao...
Daniele
|
|
|
|
|
Hi, All
I want to implement a signature mechanism. My application can
verify the validity of DLL for preventing others replace my dll.
This is just like CSP signature mechanism.
Thank you in advance for your help.
Owen.
|
|
|
|
|
Hi,
You can verify for the dll using its signatures stored in its headers. eg u can use TimeDateStamp of ur dll, or size of code base.. or u can set MinorImageVersion of the DLL when u build the data and verify the same...
u can check for size of headers sections so on...
better refer this article before u continue....
ms-help://MS.MSDNQTR.2004JAN.1033/dndebug/html/msdn_peeringpe.htm in MSDN
all the best...
gP_t_gr8
|
|
|
|
|
Hi,
I try to get the inserted row's ID (primary key) which was inserted to a table.
I tried the following API calls immediately after insert. I use the same m_hStmn for the insert and the select query.
This call is successfull however when I query the returned value using the SQLFetch and SQLGetData the returned SQLINTEGER is always zero!?
SQLExecDirect(m_hStmn, (SQLTCHAR*)_T("SELECT @@IDENTITY AS 'Ident'"), SQL_NTS)
I tried to use the more save SCOPE_IDENTITY() function, however these API calls fail.
The driver returns (for Access table) undefined function.
SQLExecDirect(m_hStmn, (SQLTCHAR*)_T("SELECT SCOPE_IDENTITY()"), SQL_NTS)<br />
SQLExecDirect(m_hStmn, (SQLTCHAR*)_T("SELECT SCOPE_IDENTITY() As [Ident]"), SQL_NTS)
In this case I got from the driver one parameter missing error code:
SQLExecDirect(m_hStmn, (SQLTCHAR*)_T("SELECT SCOPE_IDENTITY"), SQL_NTS)
Can anybody explain how can I correctly get the inserted row's ID? Why the above calls
fail ?
Thanks,
Abyss
|
|
|
|
|
How do you export a member function / class from and exe so that is can be called from a dll?
|
|
|
|
|
I've never had the need to export from an EXE, only from a DLL. Are you sure this is something you need/want?
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
|
|
|
|
|
David,
I don't see away around it for what I am trying to accomplish.
Let me explain what I am trying to do and maybe it will make for sense.
My main application is just a framework that most useful functionality will be added thru plugins.
Each screen is described in XML and all communication is done by messages.
So, here is a simple example. The main application has a screen file that says it has two buttons on it. First a theme selector button which will call the theme.dll and exit button which sends a command to close the applcation. The Theme selector button will load the Theme selector dll which loads its own screen file which has the following information.
1) Theme name
2) Theme version
3) Theme author
4) List of screenshots
5) Next Button
6) Prev Button
7) Apply Button
Since the main application has no prior knowledge of this information the plugin must be responsible to maintaining and updating this data to the main application.
That is why I need my message function to be able to send data both directions.
bool OnMessage( CSystem *pSys, CMessage * pMsg );
The main application knows that the plugin registered the following controls:
1) 2 text controls
2) screenshot control
3) 3 buttons
In the main application the user presses the Theme Selector button. The theme plugin is loaded.
On the plugins screen the next button is pushed which sends a simple message to the plugin "theme.next"
OnMessage( CSystem *pSys, CMessage *pMsg )
{
if( pMsg->GetSubject() == "theme.next")
{
mainapplication->OnMessage( ... )
}
}
Hope that makes sense.
|
|
|
|
|
In your exe source:
#ifdef EXE_EXPORTS
#define EXE_API __declspec(dllexport)
#else
#define EXE_API __declspec(dllimport)
#endif
EXE_API bool OnMessage( CSystem *pSys, CMessage *pMsg )
{
...
return(true);
}
Define EXE_EXPORTS in the project settings when building the .exe.
This will export the function in the exe and create a .lib for the .exe when you build it.
For each plugin dll you need to include a header that defines the exported function(s) e.g. OnMessage(), and link the dll with the .exe's .lib file.
...cmk
Save the whales - collect the whole set
|
|
|
|
|
Okay,
But, can you get the name of function dynamically without including the .lib like you would get the address of a function in a dll.
Oh, does it matter if this function is a member function? Would you export it the same way?
Thanks,
Steve
|
|
|
|
|
smesser wrote:
But, can you get the name of function dynamically without including the .lib like you would get the address of a function in a dll.
You can use LoadLibrary() on an exe with exported functions; however first read all the MSDN remarks for LoadLibrary().
If you exported a c++ function or a class method you have to use the mangled name in GetProcAddress().
I am guessing that it would work. LoadLibrary() would see that the specified module (the exe) is already loaded into the process and not try and call DllMain() in it. Just remember to call FreeLibrary() as well to decrease the reference count for the module (exe).
smesser wrote:
Oh, does it matter if this function is a member function? Would you export it the same way?
You would export it as you would a member function from a dll.
That is, either export the entire class:
class EXE_API MyClass {
...
);
or just the method:
class MyClass {
...
EXE_API bool MyMethod( ... );
...
);
...cmk
Save the whales - collect the whole set
|
|
|
|
|
As David mentioned the more usual way is that the exe just calls known interfaces in the dll.
For you i would suggest a similar approach.
When the exe loads the dll have it call an Init() function that passes a pointer (or reference) for the App object to the dll, then the dll can just use that pointer (or reference) to call back to the exe. You don't need to use LoadLibrary() on the exe from the dll.
I get the impression that you want this as generic as possible, but at some point you have to tell each side how to talk to the other.
...cmk
Save the whales - collect the whole set
|
|
|
|
|
cmk wrote:
When the exe loads the dll have it call an Init() function that passes a pointer (or reference) for the App object to the dll, then the dll can just use that pointer (or reference) to call back to the exe. You don't need to use LoadLibrary() on the exe from the dll.
I tried something like that and I couldn't get it to compile. I tried the following:
HWND hCore;
hCore = AfxGetApp()->m_pMainWnd->GetSafeHwnd();
CDialog* pDlg = DYNAMIC_DOWNCAST(CDialog, CWnd::FromHandlePermanent(hCore));
if (pDlg != NULL)
{
CCOREDlg *pCore1;
pCore1 = (CCOREDlg*)pDlg->GetRuntimeClass();
CSystem * pSys = NULL;
IMessage *pMsg = NULL;
g_pSystem->pCore = pCore1;
g_pSystem->pCore->OnMessage( pSys, pMsg );
}
This code works fine from the exe but externally it complains that CCOREDlg is unknown.
Maybe I was doing something wrong??
cmk wrote:
I get the impression that you want this as generic as possible, but at some point you have to tell each side how to talk to the other.
Well, that is the crux of my dilemma. Communication to the dll is simple but the other direction is some what of a buggard.
Best case scenario for me would be to export the OnMessage function from the exe and then import it in the dll. But, I am a little fuzzy on the details for doing this.
Thanks for all the input.
|
|
|
|
|
smesser wrote:
This code works fine from the exe but externally it complains that CCOREDlg is unknown.
Maybe I was doing something wrong??
Yeah, maybe.
Here are two chunks that i whipped up to test things - it works.
- build the exe as a console application
- build the dll as a non-mfc dll
- exe project defines MYEXE_EXPORTS
- dll project defines MYDLL_EXPORTS
- build exe first, copy .lib file to dll project directory
- build dll, copy .dll file to exe output directory (Debug/Release, where .exe is)
- debug exe and step through code
- or copy exe and dll to empty dir and run exe dll, watch the magic happen.
First the exe code:
<br />
<br />
#include "stdafx.h"<br />
<br />
<br />
#ifdef MYEXE_EXPORTS<br />
#define MYEXE_API __declspec(dllexport)<br />
#else<br />
#define MYEXE_API __declspec(dllimport)<br />
#endif<br />
<br />
<br />
class MyApp;<br />
<br />
typedef bool (*PLUGININIT) ( MyApp *APP );<br />
typedef void (*PLUGINTERM) ( void );<br />
typedef bool (*APPTOPLUGIN) ( long MSGID, char *MSGSTR );<br />
<br />
PLUGININIT PluginInit = NULL;<br />
PLUGINTERM PluginTerm = NULL;<br />
APPTOPLUGIN AppToPlugin = NULL;<br />
<br />
<br />
class MYEXE_API MyApp {<br />
public:<br />
int Run ( void );<br />
bool PluginToApp ( long MSGID, char *MSGSTR );<br />
};<br />
<br />
<br />
int MyApp::Run( void )<br />
{<br />
AppToPlugin(1, "First Msg");<br />
AppToPlugin(2, "Second Msg");<br />
return(0);<br />
}<br />
<br />
<br />
bool MyApp::PluginToApp( long MSGID, char *MSGSTR )<br />
{<br />
if( MSGSTR ) fprintf(stdout, "App got from Plugin: %ld %s \n", MSGID, MSGSTR);<br />
return(true);<br />
}<br />
<br />
<br />
int main( int argc, char* argv[] )<br />
{<br />
MyApp app;<br />
<br />
HMODULE lib = ::LoadLibrary(argv[1]);<br />
if( !lib ) return(-1);<br />
<br />
PluginInit = (PLUGININIT) ::GetProcAddress(lib, "?PluginInit@@YA_NPAVMyApp@@@Z");<br />
PluginTerm = (PLUGINTERM) ::GetProcAddress(lib, "?PluginTerm@@YAXXZ");<br />
AppToPlugin = (APPTOPLUGIN) ::GetProcAddress(lib, "AppToPlugin");<br />
<br />
if( !PluginInit ) return(-2);<br />
if( !PluginTerm ) return(-3);<br />
if( !AppToPlugin ) return(-4);<br />
<br />
if( !PluginInit(&app) ) return(-5);<br />
<br />
int rc = app.Run();<br />
<br />
PluginTerm();<br />
<br />
::FreeLibrary(lib);<br />
<br />
return(rc);<br />
}<br />
<br />
<br />
<br />
Now the dll code:<br />
<br />
<br />
#include "stdafx.h"<br />
#include "MyDll.h"<br />
#include <stdio.h><br />
<br />
#pragma comment(lib, "MyExe")<br />
<br />
<br />
BOOL APIENTRY DllMain( HANDLE MOD, DWORD REASON, LPVOID RES )<br />
{<br />
switch( REASON ) {<br />
case DLL_PROCESS_ATTACH :<br />
case DLL_THREAD_ATTACH :<br />
case DLL_THREAD_DETACH :<br />
case DLL_PROCESS_DETACH : break;<br />
}<br />
return TRUE;<br />
}<br />
<br />
<br />
#ifdef MYDLL_EXPORTS<br />
#define MYDLL_API __declspec(dllexport)<br />
#else<br />
#define MYDLL_API __declspec(dllimport)<br />
#endif<br />
<br />
<br />
class MyApp {<br />
public:<br />
MyApp( void );<br />
<br />
long MsgId;<br />
int Run ( void );<br />
bool PluginToApp ( long MSGID, char *MSGSTR );<br />
};<br />
<br />
<br />
MYDLL_API bool PluginInit ( MyApp *APP );<br />
MYDLL_API void PluginTerm ( void );<br />
<br />
#ifdef __cplusplus<br />
extern "C" {<br />
#endif<br />
<br />
MYDLL_API bool AppToPlugin ( long MSGID, char *MSGSTR );<br />
<br />
#ifdef __cplusplus<br />
}<br />
#endif<br />
<br />
<br />
MyApp *App = NULL;<br />
<br />
<br />
bool PluginInit( MyApp *APP )<br />
{<br />
App = APP;<br />
return(App?true:false );<br />
}<br />
<br />
<br />
void PluginTerm( void )<br />
{<br />
App = NULL;<br />
}<br />
<br />
<br />
#ifdef __cplusplus<br />
extern "C" {<br />
#endif<br />
<br />
bool AppToPlugin( long MSGID, char *MSGSTR )<br />
{<br />
if( MSGSTR ) fprintf(stdout, "Plugin got from App: %ld %s \n", MSGID, MSGSTR);<br />
<br />
if( App ) App->PluginToApp(MSGID, MSGSTR);<br />
<br />
return(true);<br />
}<br />
<br />
#ifdef __cplusplus<br />
}<br />
#endif<br />
<br />
...cmk
Save the whales - collect the whole set
|
|
|
|
|
cmk,
Thanks alot, your DA MAN.
I will try this out very shortly.
Steve
|
|
|
|
|
cmk,
It there any way you can email the files you made. I tried to reconstruct the projects from your code snipits and I am getting linking errors. I am putting something in the wrong place.
thanks,
Steve
smesser at xmission dot com
|
|
|
|
|
I tried this method but I am having linking problems
Here is what I have in my exe
#define EXE_API __declspec(dllexport)
EXE_API BOOL Message(CSystem * pSystem, IMessage * pMessage );
Here is what I have in my plugin:
#pragma comment( lib, "core.lib" ) // lib of the exe
#define EXE_API __declspec(dllimport)
EXE_API BOOL Message(CSystem * pSystem, IMessage * pMessage );
Here is the function in the plugin trying to return a message back to the .exe
BOOL PluginA::OnMessage( CSystem* pSystem, IMessage* pMessage, BOOL* Result )
{
CSystem * pSys = NULL;
IMessage * pMsg = NULL;
Message( pSys, pMsg );
return TRUE;
}
Here is the linker error
HTPCPLUGIN error LNK2019: unresolved external symbol
"int __cdecl Message(class CSystem *,class IMessage *)"
(?Message@@YAHPAVCSystem@@PAVIMessage@@@Z) referenced
in function "public: virtual int __thiscall
PluginA::OnMessage(class CSystem *,class IMessage *,int *)" (?OnMessage@PluginA@@UAEHPAVCSystem@@PAVIMessage@@PAH@Z)
Did I miss something?
|
|
|
|
|
I am working on a plug-in application similar to this. The actual EXE belongs to IBM and my part is just a DLL. The two communicate via COM interfaces. We add a few entries to the registry so that the EXE knows that our plug-in exists, and when certain events happen our plug-in is "notified" through a few standard interfaces. I know this is unlike what you are doing, but I just wanted to mention that this is at least one other way for "generic" EXEs to communicate with plug-in DLLs.
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
|
|
|
|
|
Thanks for this alternate approach. I was trying to steer clear of COM. My project started out simple and seems to grow exponentially is terms of complexity and technologies used.
Step 1) I just want a simple program that can simulate a HTPC front-end.
Step 2) It would be nice if the interface was XML based.
Step 3) Needs some direct-x cause gdi+ is so slow.
Step 4) I want to add plug-in technology. Max ability Min coupling. ( not asking much
Step 5) My back sure is itchy.... Back scratching functionality
|
|
|
|
|
Hi all,
I am using the Dundas Ultimate Toolbox in one of my MFC Programs (VC6). Sometimes (and this is exactly the problem), the program makes a debug assertation in this function:
COXMultiComboBox::OnMeasureItem
in this line:
ASSERT(AfxIsValidAddress(pRowData, sizeof(COXRowData)));
Any ideas ?
All the label says is that this stuff contains chemicals "... known to the State of California to cause cancer in rats and low-income test subjects." Roger Wright http://www.codeproject.com/lounge.asp?select=965687&exp=5&fr=1#xx965687xx
|
|
|
|
|
system information:win XP + sp2 + Microsoft Data Access Components 2.8 + VC++6.0 + Access.
application works well before i update pack to sp2, but since then it cannot work.i find the it is crashed when it run sql
"SELECT DISTINCT Info.* FROM Info WHERE Deleted = 0 ORDER BY ID DESC". i run this sql in access and it is well. i think it is winxp sp2's problem. so please give me some suggestion about it. codeguru[^]
Happy Gemini
|
|
|
|
|
Hi, I have a simple code.
#include "stdafx.h"<br />
#include <iostream><br />
using namespace std;<br />
<br />
#include <cstdlib><br />
#include <ctime><br />
typedef int DataType;<br />
<br />
void selectionSort( DataType theArray[], int n );<br />
int indexOfLargest( const DataType theArray[], int size );<br />
void mySwap( DataType& x, DataType& y );<br />
<br />
int _tmain(int argc, _TCHAR* argv[])<br />
{<br />
return 0;<br />
}<br />
<br />
void selectionSort( DataType theArray[], int n )<br />
{<br />
for (int last = n-1; last >= 1; --last)<br />
{ <br />
int largest = indexOfLargest(theArray, last+1);<br />
<br />
mySwap(theArray[largest], theArray[n - last]);<br />
<br />
}
}
<br />
int indexOfLargest( const DataType theArray[], int size )<br />
{<br />
int indexSoFar = 0;
for (int currentIndex = 1; currentIndex < size; ++currentIndex)<br />
{
if (theArray[currentIndex] > theArray[indexSoFar])<br />
indexSoFar = currentIndex;<br />
}
<br />
return indexSoFar;
}
<br />
void mySwap( DataType& x, DataType& y )<br />
{<br />
DataType temp = x;<br />
x = y;<br />
y = temp;<br />
}
Compiler gives the error
d:\CD\myProjects\hw2Q4\hw2Q4.cpp(14): fatal error C1075: end of file found before the left brace '{' at 'd:\CD\myProjects\hw2Q4\hw2Q4.cpp(13)' was matched
There is no unmatched curly, any help would be appricated.
|
|
|
|
|
add:
#include <tchar.h>
after
#include "stdafx.h"
Steve
|
|
|
|
|
|