How to handle custom-messages in VBA from a custom C++ DLL

L

LhK-Soft

Hi,
I'm active in VC++ for several years now, so I know some things (I think).
Using MS-Access I store a db with lots of entries and uses the VBA
techniques to export those data to e.g. HTML, XML and other kind of data.
I'm using MS-VC++6.0-Enterprise (with sp6) at a NT4-Workstation (sp6a) and
MS-Access97 (from MS-Office97). Reason that I won't upgrade to latest
Office/VisualStudio is that I must ensure that any application I develop
still works at Windows9x (and so on) - so for full compatibility with any
configuration.

Lately I ran into a problem, while I use an external function from a VC++
DLL (DLL build as a 'MFC Regular DLL' using dynamic linkage over MFC) to
export all my data in a fixed file (must use the DLL for performance, while
I
first create a directory with files in VBA then use the functions inside the
DLL to grab the contents of the exported directory and put it all into a
binary file - it's intended to be used by an installation procedure for
customers).

The DLL creates a worker-thread in which it creates a modal-dialog box using
'DialogBoxIndirectParam'. This Dialog stays on top of the calling HWND until
it receives a message from the calling thread that it may close (using
'EndDialog').
From start-up until end of the dialog it receives custom message
(combinations of WM_USER) to display a progress-bar of the running thread.
This works fine when calling from a MFC-module (.exe) but appearently it
doesn't when called from MS-Access: the dialog popups, but halfway it stops
receiving messages and in rare cases it does handle all send messages, but
then it won't disapear from the desktop when the dll has finished.

I gues the problem is MS-Access, maybe it's STA (single threaded) while my
DLL is multi-threaded, so I would try another solution : sending the
progress
messages directly to the calling Access module. But then I come into my
problem.
How can I let MS-Access react at my own 'custom' messages, while the VBA
module is still 'waiting' for my DLL to finish.
I already tried to develop a COM object, but while this asks a lot of
development it didn't resolve my problem!

If anyone would know a good suggestion/answer for me, I would appreciate it
very much. Currently I run the exported DLL-function in VBA without popping
up the progress dialog (Access is blocking anyway while my DLL is in
progress, and that can take up a very long time, while I've got a lot of
data
in the DB), so Access won't react strange anymore.
I also tried to 'talk' directly to MS-Access by linking to the Access-COM
module in VC++ so I could try to get an interface to the Access.Application
object and so modify the statusbar, but as soon I do MS-Access popups with a
Kernel failure !?

So I come with my question, would it be possible to run my DLL-procedure in
a seperate thread, so Access can go into idle-status, so it could react to
custom messages I send from the DLL, so Access can write to the statusbar
itself...?
But is it possible at all, to launch a seperate thread in MS-Access? Or
should I better call a seperate thread from inside the DLL and then return
immediately so I could have MS-Access to go into a timer-loop (event
'OnTimer') - but then I still don't know how to react at custom messages
from
my DLL.

Thank you very much if you can help me!
--
Laurens Koehoorn
\\\ | ///
( @.@ )
+-----------oOOo------(_)------oOOo---------------+
Author of VCDwizard, get your copy at
http://www.labdv.com/vcdwizard/
Author of lkVCDimager, get your copy at
http://lkvcdimager.sourceforge.net/
 
B

Bonj

The DLL creates a worker-thread in which it creates a modal-dialog box

This is a bad idea.
For optimum stability, an application should do *all* user interface
interaction in a single, primary UI thread.
There are exceptions to this rule (see 'UI threads') , but AFAIK they are
rare!

using
'DialogBoxIndirectParam'. This Dialog stays on top of the calling HWND
until
it receives a message from the calling thread that it may close (using
'EndDialog').
From start-up until end of the dialog it receives custom message
(combinations of WM_USER) to display a progress-bar of the running thread.
This works fine when calling from a MFC-module (.exe) but appearently it
doesn't when called from MS-Access:

How does it call it?

the dialog popups, but halfway it stops
receiving messages and in rare cases it does handle all send messages, but
then it won't disapear from the desktop when the dll has finished.

I gues the problem is MS-Access, maybe it's STA (single threaded)

I would guess it uses worker threads internally, but to do just that - work,
not create a UI.
Access VBA adheres to the COM object model, which states that any COM object
must only have its members accessed from the thread that created it.
while my
DLL is multi-threaded, so I would try another solution : sending the
progress
messages directly to the calling Access module. But then I come into my
problem.
How can I let MS-Access react at my own 'custom' messages, while the VBA
module is still 'waiting' for my DLL to finish.

If your VBA code can create a form that you know the hWnd of, just pick an
event handler that isn't being used for the form's operation, then just
figure out the corresponding message that triggers that event, and post it
to the form.
If that doesn't suit your needs, create a dialog box in the function of the
DLL that is exported to VBA (not a thread function) - then tell the worker
thread the hWnd of this window to post your messages to, which the DlgProc
can intercept for the progress bar.

I already tried to develop a COM object, but while this asks a lot of
development it didn't resolve my problem!

COM requires strict laws regarding threading like it does on many things, in
order to be language-neutral, notably the one I mentioned above. But it
doesn't sound like you need a COM object here... a regular DLL can export to
VBA, create a dialog box, and create a worker thread - it's the order you do
them in that's important... i.e. the just create the dialog from the thread
that the VBA module called, and then just tell the worker thread its hWnd.

If anyone would know a good suggestion/answer for me, I would appreciate
it
very much. Currently I run the exported DLL-function in VBA without
popping
up the progress dialog (Access is blocking anyway while my DLL is in
progress, and that can take up a very long time, while I've got a lot of
data

Perhaps another solution you could consider is not to use VBA at all, but to
write a self-contained application that connects to the Access database via
ADO.
This could then be expanded both in terms of additional
data-churning/viewing functionality, aswell as easily ported to SQL server
should you ever need to do that.
in the DB), so Access won't react strange anymore.
I also tried to 'talk' directly to MS-Access by linking to the Access-COM
module in VC++

Take a step back and try a different tack, perhaps... this sounds messy!

so I could try to get an interface to the Access.Application
object and so modify the statusbar, but as soon I do MS-Access popups with
a
Kernel failure !?

So I come with my question, would it be possible to run my DLL-procedure
in
a seperate thread, so Access can go into idle-status, so it could react to
custom messages I send from the DLL, so Access can write to the statusbar
itself...?

But is it possible at all, to launch a seperate thread in MS-Access?

No! Now I know for a fact that that's *definitely* impossible...
 
L

LhK-Soft

Tx. Bonj for your reply, it maked me a lot more clear.

I try the suggestion you mentioned :

"Bonj" <benjtaylor at hotpop d0t com> wrote in message
How does it call it?

Access calls a function from the DLL, the DLL creates a worker-thread. The
worker-thread creates a dialogbox and returns this HWND to the calling
dll-function.
Then that function creates a class in which the actual job is done and uses
the HWND of the dlg in the worker-thread to send its status-messages to.
So actually, access isn't sending any messages to my dll; the exported
function in the dll is doing it.
If that doesn't suit your needs, create a dialog box in the function of the
DLL that is exported to VBA (not a thread function) - then tell the worker
thread the hWnd of this window to post your messages to, which the DlgProc
can intercept for the progress bar.

I think this would solve most of my problem.
By turning things around : create the modal dialog in the function which is
called by access, and do the job in a worker-thread.
That must work though while when you call the api-function
"DialogBoxIndirectParam", it only returns when the system couldn't create
the dialog (but I've tested it all, and it does) or when one triggerd the OK
or CANCEL buttons (which I do programmaticly by responding to a custom
message). While the api-function is running, the dialog-proc does its job
'correctly'.
So Access still will be "blocking" but hopefully I get my job done.
Perhaps another solution you could consider is not to use VBA at all, but to
write a self-contained application that connects to the Access database via
ADO.
This could then be expanded both in terms of additional
data-churning/viewing functionality, aswell as easily ported to SQL server
should you ever need to do that.

I was thinking about that, but the problem is that the only way of running
external modules in Access' VBA is via the function "Shell", which runs
asynchronous. So it launches any external application but then returns
immediately to Access.
The idea is that one should wait, before closing Access or doing other jobs
inside Access.
The purpose of mine DLL works together with a custom export I do in VBA (VBA
'prepares' the data in a custom file layout, then my DLL will 'pack' these
files to 1 single binary so it can be used by an installer I wrote for this
data). It's not the intension to start this exporter twice (accidently), I
don't know what would happen but it won't be great.

So I'll try the first suggestion you gave.
Thank you very much for your help!

--
Laurens Koehoorn
\\\ | ///
( @.@ )
+-----------oOOo------(_)------oOOo---------------+
Author of VCDwizard, get your copy at
http://www.labdv.com/vcdwizard/
Author of lkVCDimager, get your copy at
http://lkvcdimager.sourceforge.net/
 
L

LhK-Soft

Hi Bonj (and anyone else too ;-) ),

Tried the suggestion (follows) :

But access still wouldn't accept it.
Then I thought, what if I wouldn't use a thread at all?
While the actual job is done in a class and the progress-dialog is done in
another class (not MFC, so safe for VB(A)), what would happen if I link both
classes together into 1 class? Well, I finally like the results.
Now, no thread will be started in the DLL and access runs my task while
having the progress-status in a seperate modeless dialog (comming from the
dll).

The C++ source looks like following:

extern "C" DWORD WINAPI WritePacket(LPCTSTR lpszPacket, LPCTSTR lpszSrcPath,
HWND hWndAccessApp)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());

CPacketWriter* writer=new CPacketWriter(AfxGetInstanceHandle(),
hWndAccessApp);
// create Modeless Dialog
if (writer->DoModeless() == NULL)
{ // failed to create the dialog ??
delete writer;
return 0;
}

DWORD ret = writer->WritePacket( lpszPacket, lpszSrcPath );
writer->SendProgressMsg(prgEND, 0);
delete writer;

return ret;
}


--
Laurens Koehoorn
\\\ | ///
( @.@ )
+-----------oOOo------(_)------oOOo---------------+
Author of VCDwizard, get your copy at
http://www.labdv.com/vcdwizard/
Author of lkVCDimager, get your copy at
http://lkvcdimager.sourceforge.net/
 
B

Bonj

But access still wouldn't accept it.

How are you defining "wouldn't accept it" ? What is the error message, if
any, and at what point does it occur?

I see your point about not wanting Access to "block". FWIW, I have seen a
spurious error message before in Excel that says "Microsoft Excel is waiting
for another application to complete an OLE action" when it is executing a
long COM call - the call is working fine, but it pops up a message box
saying that every 10 seconds until it completes. I don't know whether that's
what you're getting, but you could possibly address that by having a
separate process, and use ShellAndWait (see below)
Then I thought, what if I wouldn't use a thread at all?

If you don't use a thread at all, the DlgProc won't be able to process the
progress bar update messages as it will be on the same thread that's doing
the calculations. You just need to make sure the CreateDialog (or
equivalent) occurs in the same thread that Access's VBA is in - after that,
it can create worker threads. The worker thread could send a custom
'finished' message to the dialog's hWnd, which it could intercept and call
EndDialog, thus causing the call to CreateDialog to return (and back into
the VBA).
I was thinking about that, but the problem is that the only way of running
external modules in Access' VBA is via the function "Shell", which runs
asynchronous. So it launches any external application but then returns
immediately to Access.
The idea is that one should wait, before closing Access or doing other
jobs
inside Access.

Do a search for "ShellAndWait" on google - it is a widely documented method
of calling CreateProcess, and then doing a loop, calling WaitForSingleObject
on the process's handle with a timeout of, say, 50ms (which you pass to it),
this means it "spins its wheels" in a loop, and it's executing a method
every 50ms, and it only breaks out of the loop when the process terminates.
It could possibly solve the bug I remembered above, if that was the case
with yours.
 
L

LhK-Soft

Bonj, tx. (again) for your response..

Bonj said:
How are you defining "wouldn't accept it" ? What is the error message, if
any, and at what point does it occur?

"wouldn't accept it" : The dialog popup's, but can't get removed from
access' desktop when it's finished. Properly Access97 doesn't allow me to
start other threads when called external functions from a DLL when using UI.
I see your point about not wanting Access to "block". FWIW, I have seen a
spurious error message before in Excel that says "Microsoft Excel is waiting
for another application to complete an OLE action" when it is executing a
long COM call - the call is working fine, but it pops up a message box
saying that every 10 seconds until it completes. I don't know whether that's
what you're getting, but you could possibly address that by having a
separate process, and use ShellAndWait (see below)

Looks handy that function "ShellAndWait", after I've searched the Net I
would use it whenever I've got a more sophisticated task to do.. but for the
moment I'm happy with the result.
With "blocking" I mend that Access starts the call to the external function,
but then waits until the external function returns. While it waits, the
whole desktop of Access "freezes" (even the assistent-icon), so it doesn't
do any refreshing of its desktop/windows.
I gues this wouldn't be the case when I would call "DoEvents" at a regulare
base (when I used "ShellAndWait").
If you don't use a thread at all, the DlgProc won't be able to process the
progress bar update messages as it will be on the same thread that's doing
the calculations. You just need to make sure the CreateDialog (or
equivalent) occurs in the same thread that Access's VBA is in - after that,
it can create worker threads. The worker thread could send a custom
'finished' message to the dialog's hWnd, which it could intercept and call
EndDialog, thus causing the call to CreateDialog to return (and back into
the VBA).

While when running a dialog as Modal, the call to "DialogBox" would not
return until the DlgProc has called "EndDialog" (usually in respons of a
message, like OnOK and OnCancel), but when running a dialog as Modeless, the
call to "CreateDialog" will return immediately (if the creation of the
dialog succeeded and the WM_INITDIALOG call has been made, it returns the
dialog's HWND) allowing me to run other things in the same thread besides
the existance of the dialog (I gues, in case of a modeless dialog, the C/C++
API launches its own thread) - but I've figured out I shouldn't call a
SendMessage/PostMessage to the dialog itself too much (instead I must use a
regular function when I want have things to be changed in the dialog).
To have "full" access to all members of the dialog-class (not a child of
MFC's CDialog, while CDialog calls some invalid methods which doesn't allow
me to create/run a dialog from inside a regular DLL), I derived the
worker-class (which does the actual job) also from the dialog-class which
does all things to display the dialog and dlgproc :

[code/start]
class ClkBaseDlg
{ // base class for all my "custom" dialogs when called from a DLL
....
public:
virtual BOOL DoProcessing(...); // processes any message from the DlgProc
HWND DoModeless(void);
};

class CProgressDlg : public ClkBaseDlg
{ // "independant" progress-dialog
....
};

class CExporter : public CRuntimer, public CProgressDlg
{ // class encapsulating all required stuff, when called from VBA
....
};

// in file lkBaseDlg.cpp
static BOOL CALLBACK myDlgProc(HWND hWnd, ...)
{
....
ClkBaseDlg* theDlg = GetMyDlg(hWnd);
if (theDlg)
return theDlg->DoProcessing(...);
//else
return FALSE; // indicating message has not been processed
}

ClkBaseDlg::DoModeless()
{
....
HWND ret = CreateDialogIndirectParam(m_hOwnerModule,
(LPCDLGTEMPLATE)m_DlgTemplate,
m_hWndParent, (DLGPROC)myDlgProc, (LPARAM)this);
....
return ret;
}

[code/end]

In previous code-sample, CRuntimer is a base class with basic
functions/variables which are the same for exporting/importing
(packing/unpacking) data.
CExporter would be the class specific for exporting the prepared data (by
VBA) to a single binary file which then can be unpacked by the installer I
created in another application.

This seems to be working, when it's called from the DLL from a VBA-module in
Access. While Access still is "blocking" anything at its own desktop, the
dialog in the DLL gets updated (so it's "alive").
Do a search for "ShellAndWait" on google - it is a widely documented
method

So I did.. tx.

cu.
 
B

Bonj

"wouldn't accept it" : The dialog popup's, but can't get removed from
access' desktop when it's finished. Properly Access97 doesn't allow me to
start other threads when called external functions from a DLL when using
UI.

You're not supposed to create extra threads from Access97 - do this from,
say, one of the handlers for a button on the dialog (WM_COMMAND), or when
the dialog starts, WM_INITDIALOG - i.e. *on the C++ side* - in the DLL. The
DLL starts the modal dialog box, the DLL *also* starts a thread - that
doesn't mean the dialog is running in the worker thread - that will only be
the case if the worker thread's thread procedure calls CreateDialog. If the
exported function calls CreateDialog, and the dialog's DlgProc starts the
worker thread, then Access should block, but the dialog itself should be
responsive.
Looks handy that function "ShellAndWait", after I've searched the Net I
would use it whenever I've got a more sophisticated task to do.. but for
the
moment I'm happy with the result.

What's your final configuration, like I said or slightly different?
With "blocking" I mend that Access starts the call to the external
function,
but then waits until the external function returns. While it waits, the
whole desktop of Access "freezes" (even the assistent-icon), so it doesn't
do any refreshing of its desktop/windows.

That shouldn't matter. It shouldn't mean the dialog box freezes aswell. If
it does, try passing NULL to the hWndParent parameter - instead of Access's
window.
If some component is doing an operation on the database, you shouldn't
*want* the users to have access to the database while it's running, as they
should know that the database is being updated. It won't look wrong. If
you've explicitly taken the decision that user-interaction with the Access
desktop while the function is running is something that is needed, then you
*really* need to write it in ADO.
I gues this wouldn't be the case when I would call "DoEvents" at a
regulare
base (when I used "ShellAndWait").

Ermm.... I don't know..
Like I say, if you *insist* on user-interaction with the database from an
Access desktop process, you don't really want that process also running a
time-consuming calculation.
While when running a dialog as Modal, the call to "DialogBox" would not
return until the DlgProc has called "EndDialog" (usually in respons of a
message, like OnOK and OnCancel),
but when running a dialog as Modeless, the

Are you saying that you are having a *modeless* dialog box? If so, then how
does Access know when it's finished? What if the Access function that
started the dialog has completed and no more code is running in Access, and
the user shuts Access down before the code has finished?
What problems do you have with a modal dialog box that a modeless one
solves?
I'm just trying to get you to understand that having Access run a dialog
that's supposed to look like it's in a completely separate process to
Access, but isn't because you can't see how else to communicate the results
back, is a kludge. Either Access blocks, or use a separate process. Anything
else (I can't quite figure out what you've finally gone for, but..) I'd be
very interested to hear how you implement the calls and the return of
information, and why you reckon this particular way of doing it isn't a
hack - not least because I'd want to know how to do it myself, since I
obviously didn't know it to advise you earlier!
call to "CreateDialog" will return immediately (if the creation of the
dialog succeeded and the WM_INITDIALOG call has been made, it returns the
dialog's HWND) allowing me to run other things in the same thread besides
the existance of the dialog (I gues, in case of a modeless dialog, the
C/C++
API launches its own thread) -
but I've figured out I shouldn't call a
SendMessage/PostMessage to the dialog itself too much (instead I must use
a
regular function when I want have things to be changed in the dialog).
To have "full" access to all members of the dialog-class (not a child of

I don't know what you mean by "full" access....
MFC's CDialog, while CDialog calls some invalid methods which doesn't
allow

Well, that's probably the root of all your problems. MFC is ghastly,
bloated, cumbersome, dependent, obscure and probably buggy. I personally
*hate* it.
If you want RAD, there's VB6 or C#, if you want COM, there's ATL (if you
must), if you want controllability, there's straight C/C++, so *why* there
is a need for the abomination that is MFC god only knows.
 
L

LhK-Soft

Hi Bonj,

Bonj said:
(snip)

What's your final configuration, like I said or slightly different?

Sorry, don't remember any more what you said.
But the config is something like this :
- using Access97 at winNT4
- a "Regular MFC" DLL, the dialog is created inside the DLL (so nothing to
deal with the "limitations" of VB/A)
- Access imports the function from the dll using a "declare function..."
inside the VBA code
- in a sub/function of access' vba, I call the imported function:
<code>
If MyDllFunc(...) = 0 Then
' response on failure
else
' all wend fine
end if
</code>
- Access calls "MyDllFunc" and only steps into the next line after all the
dll-code (including startup and dying of the dialog) has finished.

That shouldn't matter. It shouldn't mean the dialog box freezes aswell. If
it does, try passing NULL to the hWndParent parameter - instead of Access's
window.

that won't work.
"CreateDialogBox" and/or "DialogBox" requires to have a valid HWND or the
dialog won't be able to popup/created.
So if one would give NULL for the HWND, the dll catches this by getting it
using "::GetActiveWindow" - so the chance for failure would be minimized.

If some component is doing an operation on the database, you shouldn't
*want* the users to have access to the database while it's running, as they
should know that the database is being updated. It won't look wrong. If
you've explicitly taken the decision that user-interaction with the Access
desktop while the function is running is something that is needed, then you
*really* need to write it in ADO.

I'm not, but I hoped, like I can in C++ (by using different threads) that at
least the desktop gets updated (rewritten), even if the user can't do any
input onto the calling application (e.g. when some other app get's focus and
overlaps access' desktop and then after a while access returns to have the
focus: it's desktop will not be rewritten because it "blocks" during
processing of the DLL).
Are you saying that you are having a *modeless* dialog box? If so, then how
does Access know when it's finished? What if the Access function that
started the dialog has completed and no more code is running in Access, and
the user shuts Access down before the code has finished?

Access isn't the owner of the dialog, though it's the owning window (the
code in the dll, which is the actual owner is using the dialog just for
processing status messages).
So the internal DLL's function starts up the dialog, and when it's done it
closes the dialog again.
While Access "blocks" one can not pre-terminate access while the dialog is
at the user's desktop: Access is waiting for the dll-function to return, but
that function only returns when it's finished or when an error occures (in
which case the dialog will get closed).
What problems do you have with a modal dialog box that a modeless one
solves?

Appearently, a modal dialog will stay on top of the window and only works in
a different thread when other code (the "controller" of the dialog) should
run. Knows, it's not the user who controls the dialog but code. But the
problem is that in this case I must use threads and windows-messages (even
if it are user-messages) which seems to bother Access. While using a
modeless dialog, I don't need a seperate thread neither do I need to use
messages in order to control the dialog - so a better solution for my task.
Even so, if a modal dialog is used - it depends on time of the calling
thread for its rewriting methods - but while Access "blocks" while it's
waiting for the dll to return it even don't show the modal dialog (it does
in debug-mode, which puts the active thread into "idle" status while I'm
stepping through the code) as a modeless dialog seems to use its own thread
(created in the win32 api) - like one can also start a FileDialog or
FolderBrowser from VBA.
very interested to hear how you implement the calls and the return of
information, and why you reckon this particular way of doing it isn't a
hack - not least because I'd want to know how to do it myself, since I
obviously didn't know it to advise you earlier!

That's not very simple to explain.
First of all, I'm using a realy "MFC Extension DLL" which exports classes
only, which only works with MFC!
In it, I've recoded lots of the basic knows classes to make life easier for
the windows developpers like me (I program MFC for over 10years now - since
the good old days of Win311). There's an undocumented MFC-class
"CDialogTemplate" (look into your MFC's source-code for the file
"afxpriv.h"), which CDialog uses to load a dialog-resource into memory for
putting it onto the desktop. There's just one problem, it uses MFC for all
kind of things - resulting that one cannot use CDialog for dialogs in DLL's
(unless it's an Extension DLL). So by rewriting the code of CDialogTemplate
and appending lots of extra tools to it, I'll be able to use my own kind of
CDialog classes (but *NOT* using MFC at all) to load an run dialogs from
resources inside a (regular) DLL. So the DLL I'm using is a "MFC Regular"
DLL, linked into MFC (dynamicly, while nearly all required dlls (except for
1 or 2) are available in Windows these days and into my own Extension DLL),
and which then can export its tools (using MFC or not) to the outside using
plaing 'extern "C" ... WINAPI ...(...)' declarations (and using a .def file
of course). Names aren't decorated so VB(A) and Delphi users can use the
tools too.

By using a base class which does do all required things, I don't have to
"re-event" the wheele each time to do the things I want (like loading the
resource, the dlgproc etc). In fact, while I'm in C++, the basedialog-class
uses nearly the same kind of declarations for custom messages etc. which are
used in MFC's CDialog. Only, one needs to know what to do, because mine
class isn't compliant (nor handled/recognized) by MFC's ClassWizard.

Well, that's probably the root of all your problems. MFC is ghastly,
bloated, cumbersome, dependent, obscure and probably buggy. I personally
*hate* it.

It's not my problem! And I don't hate it (I love it), but MFC only works
when used with MFC - not outside.
You can use it in Dlls but shouldn't export anything of it : the caller must
supply its own memory to fill the results or you should replace things of it
with "native" win32 code when exporting - like I did entirely.
It seems to be working - but appearently even native win32 code is not
always accepted (like in my problem: access doesn't like to have other
threads running in its own process which aren't created by access itself).
In VC++ one can create other processes only in the form of exe-cutables, in
which case I could be working with Shell (of access) in anytime. But that's
not my intension. I create VBA to make life easier for me when working in
Access and develop in C++ (for dlls) to link even more complex code into VBA
(while I realy *hate* VB and so VBA too).
Neve-the-less, while I've managed a solution for my taks - I'm still
thinking to rewrite the C++ code and make it as much as possible VBA code
(so then I realy can write to the statusbar of access for
processing-messages) and only create some worker-code in c++ which I export
seperately to keep using the same stricted output which I require.
The final binary file must be used by an installer, which is a simple
MFC-commandline program, which calls a function in the DLL which "unpacks"
the file to a path from registry (put there after an InstallShield
installation of the actual MFC-program).
So that's why I use the DLL. Whenever I would make a change in the DLL, both
are updated (packer and unpacker).

cu.
--
Laurens Koehoorn
\\\ | ///
( @.@ )
+-----------oOOo------(_)------oOOo---------------+
http://www.geocities.com/SiliconValley/Pines/6750/
Author of VCDwizard, get your copy at
http://www.labdv.com/vcdwizard/
Author of lkVCDimager, get your copy at
http://lkvcdimager.sourceforge.net/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top