15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Showing Dialogs from a DLL

Marcus -- bmarcus@erols.com
Tuesday, May 07, 1996

System: NT3.51, service pack 3;  VC++ 4.1

I have a question concerning dialogs and dlls. I'm in the process of converting what was once a 
large .EXE (containing many dialogs in its resource file) that will now be a small .EXE that calls a 
large .DLL (that will contain most of the previous dialogs).  The DLL is to have the dialog 
resources and the EXE will call a function (DLL entry point) that will show a particular DLL dialog. 
The calling function from the EXE looks like this:
	void CMass32View::OnShowTestDlg() 
	{
		ShowMassDBDlg(this->m_hWnd,INDEX);	
	}

The function in the DLL looks like this:
extern "C" __declspec( dllexport ) BOOL ShowMassDBDlg(HWND hWndParent,int dialog)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	
	TRY
	{
		switch ( dialog )
		{
			case INDEX:
				CSensorDB  SensorDialog;
				int result = SensorDialog.DoModal();
				if (result == -1)
					AfxMessageBox("Couldn't create dialog");
				else if (result == IDABORT)
					AfxMessageBox("Some other error with dialog");
				else 
					AfxMessageBox("This should have worked");
				:
				:
				:

The problem is that DoModal() is always returning -1 (can't create the dialog). Why???

Please post response or e-mail me directly at bmarcus@erols.com

Thanks,

Brad Marcus



JCS -- JCS@ficsgrp.com
Friday, May 10, 1996

[Mini-digest: 3 responses]

This is a problem concerning resources that are not available, it think.

You should include the following rule in your main header file (the one   
defining the class derived from CWinApp)

extern HINSTANCE the_hinstDLL;

in the corresponding .cpp file you then define

HINSTANCE the_hinstDLL;

and override the :InitInstance() function as followes:

BOOL CAskApp::InitInstance()
{
 // TODO: Add your specialized code here and/or call the base class

 the_hinstDLL = AfxGetInstanceHandle();

 return CWinApp::InitInstance();
}

then, before calling your Modal() function, set the resource handle:

 HINSTANCE previous_hinst = AfxGetResourceHandle();

 AfxSetResourceHandle(the_hinstDLL);

 CSensorDB  SensorDialog;
 int result = SensorDialog.DoModal();
 ...
 AfxSetResourceHandle(previous_hinst);

Hope this helps

Jan Castermans

-----From: joew@statsoftinc.com (Joe Willcoxson)

Try using AfxSetResourceHandle() and AfxGetResourceHandle().  Your DoModal
is probably failing because you're app can't find the dialog resource in
your .EXE file.  If you set the resource handle to your DLL instance, then
it will be able to find it.  However, don't forget to set it back.
Joe Willcoxson (joew@statsoftinc.com)
http://www.statsoftinc.com

Author of the FREE WorldCom MFC library:  
http://users.aol.com/chinajoe/wcmfclib.html


-----From: Jeff Lindholm 

You need to ensure that you are using the DLL's resources.
Call AfxSetResource() to the DLL's instance and then set it back to the
Application's after you create the dialog.

Jeff



David Mcalister -- davidm@rackwick.demon.co.uk
Friday, May 10, 1996



----------
From: 	Marcus
Sent: 	07 May 1996 20:40
To: 	MFC list
Subject: 	Showing Dialogs from a DLL

System: NT3.51, service pack 3;  VC++ 4.1

I have a question concerning dialogs and dlls. I'm in the process of converting what was once a 
large .EXE (containing many dialogs in its resource file) that will now be a small .EXE that calls a 
large .DLL (that will contain most of the previous dialogs).  The DLL is to have the dialog 
resources and the EXE will call a function (DLL entry point) that will show a particular DLL dialog. 
The calling function from the EXE looks like this:
	void CMass32View::OnShowTestDlg() 
	{
		ShowMassDBDlg(this->m_hWnd,INDEX);	
	}

The function in the DLL looks like this:
extern "C" __declspec( dllexport ) BOOL ShowMassDBDlg(HWND hWndParent,int dialog)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	
	TRY
	{
		switch ( dialog )
		{
			case INDEX:
				CSensorDB  SensorDialog;
				int result = SensorDialog.DoModal();
				if (result == -1)
					AfxMessageBox("Couldn't create dialog");
				else if (result == IDABORT)
					AfxMessageBox("Some other error with dialog");
				else 
					AfxMessageBox("This should have worked");
				:
				:
				:

The problem is that DoModal() is always returning -1 (can't create the dialog). Why???

Please post response or e-mail me directly at bmarcus@erols.com

Thanks,

Brad Marcus


I enclose an excerpt from comp.os.ms-windows.programmer.tools.mfc


pat@eco.twg.com wrote:
> 
> I've written a simple MFC based DLL which is in turn used by
> another MFC application.
> 
> When the MFC based DLL is statically linked  with the MFC library
> my application performs as expected.  (i.e. I can bring up a dialog box
> from within the DLL)
> 
> When I change the General project settings such that the DLL uses
> MFC in a shared DLL I can no longer bring up the same dialog box.
> The following messgage appears in the output window:
> "First-chance exception in test_mfc_dll.exe (NTDLL.DLL): 0xC0000005: Access Violation."
> 
> What concepts or "MFC features" am I missing.
> 

The problem is with loading the dialog's resources. This question seems
to come up fairly frequently, and I've posted the solution a couple of
times in the last couple of months. I assume there's a FAQ for this
group, but since I have no details on where to get it, nor whether
this info is there, I'll post it again.

------------------------------------------------------------

What you need to do is get the instance handle of your DLL and make
that the current app resource handle. To do that, add the following
code to your DLL:

// Instance handle of this DLL
static HINSTANCE hInst_DLL;

/////////////////////////////////////////////////////////////////////////////
// Initialization of MFC Extension DLL
static AFX_EXTENSION_MODULE NEAR extensionDLL = { NULL, NULL };

extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
   hInst_DLL = hInstance;	// save for later
   if (dwReason == DLL_PROCESS_ATTACH)
   {
      if (!AfxInitExtensionModule(extensionDLL, hInstance))
         return 0;
   }

   return 1;   // ok
}

This will get called automatically when the dll is loaded.
In your function that calls DoModal() do the following:

{
   // set resource handle to this dll, so our resources can be found
   HINSTANCE hOldRes = AfxGetResourceHandle(); // save for restoring
   AfxSetResourceHandle(hInst_DLL);

   CMyDialog dlg;
   dlg.DoModal();

   AfxSetResourceHandle(hOldRes);	// restore app's handle
}

BTW, I got most of this from the DLLHUSK sample that comes with VC4.0.

Ha

begin 600 WINMAIL.DAT
M>)\^(C$(`0:0" `$```````!``$``0>0!@`(````Y 0```````#H``$(@ <`
M& ```$E032Y-:6-R;W-O9G0@36%I;"Y.;W1E`#$(`0V ! `"`````@`"``$$
MD 8`# $```$````,`````P``, (````+``\.``````(!_P\!````/P``````
M``"!*Q^DOJ,0&9UN`-T!#U0"`````&UF8RUL0&YE=&-O;2YC;VT`4TU44 !M
M9F,M;$!N971C;VTN8V]M```>``(P`0````4```!33510`````!X``S !````
M$0```&UF8RUL0&YE=&-O;2YC;VT``````P`5# $````#`/X/!@```!X``3 !
M````$P```"=M9F,M;$!N971C;VTN8V]M)P```@$+, $````6````4TU44#I-
M1D,M3$!.151#3TTN0T]-`````P``.0`````+`$ Z`0````(!]@\!````! ``
M``````(]+ $$@ $`'P```%)%.B!3:&]W:6YG($1I86QO9W,@9G)O;2!A($1,
M3 `$"@$%@ ,`#@```,P'!0`*``D`#0`P``4`+0$!(( #``X```#,!P4`"@`)
M``T`# `%``D!`0F `0`A````,SE$0T9$13DS.4%!0T8Q,3A&0S@P,#@P0S@Q
M-S@T144`;@$[@``'@`># $````%````4TU44 `````>`!\,`0``
M``@```!G871E=V%Y``,`!A"GP5J=`P`'$/T*```>``@0`0```&4````M+2TM
M+2TM+2TM1E)/33I-05)#55-314Y4.C W34%9,3DY-C(P.C0P5$\Z349#3$E3
M5%-50DI%0U0Z4TA/5TE.1T1)04Q/1U-&4D]-041,3%-94U1%33I.5#,U,2Q3
M15)624-%``````(!"1 !````Q D``, )```C% ``3%I&=2>+AEW_``H!#P(5
M`J0#Y 7K`H,`4!,#5 (`8V@*P'-E=.XR!@`&PP*#,@/&!Q,"@[HS$PU]"H (
MSPG9.Q7_>#(U-0* "H$-L0M@;G)G`= U-PK[$O(,`6,-`$ @"H4*BVQI,3B"
M, +1:2TQ-#0-\&<,T!S#"UDQ-@J@`V!T^P60!4 M'N<*AQV;## >9OI&`V$Z
M'^X>9@R"!= *P/AC=7,?CR"=!F ","'/"2+;,#2V092&Q3H!4,RXU,2P@$?! 
MR! `]8&__.B0]R)A%R*'!P;PN =/U$"G,R$3-!"K$ZX"/00('_2U,[Y#S@"H5+(D92,D)/
MEV ,>D 2A(D,B(%]?ZP6!/,!P
M!9 H/))C0%#0Q0`@($0`0D]/1]!<+-Q(5UW@.B!=D5 *P"81-BQ0\3O5*0J&
M6PM!1@!87TU!3D%'10!?4U1!5$4H06AF>$<2`%,!D%*!3>L$<%*P96L295H`
M7B!76G%76E1265H_6TP#X73_$;!!($R&:$=;EV[?6[5&4-\1\#H`7>)72W*]
M0R8!0U#^BMT,Q4K %0#UVJT>@;VMQWP= 6@!W?WB*
M/D H>79YX*\U\=@#V 8R%R`V %P' 1
M_W!0@B^&[X1%BO^'+X!;2R!O2Z%1X8%!.B1W!;!6T&3_BL]RVW1/DH^3GY2K
M4\D>8?\"8#;@2Y,_(GK72Y('0#]@^S:P0R%T"' [DQRP02$`<(>!B$Q82N%7
M:'D_G-#],ZQ00^!SLE#024%#,5#0]P" B3%C(2T`P ,1B2$[X-L6`!ZP;"AP
M/S%B`, CPMY !) &\#S0!:!MELX`<,5B`"PSK$)R83R (Z__-7@;3!G/.9@)
M\&0P23 Z83\#H&- .V$%,3,#H:%P+ME),"YM73 R,60R(#S0DQYA" 
M+8G_S,#BA)A*&A&MIZ^H:+!0+'[/7)J
MX&X$D = /:(OXC>1]P) ,D&0$75P040C85:SH?\C]J^@+3(]044Q$<&R);ZD
M_T3 8<'#X07 OP<] H;52@= 1X#TV
M"&!TGG#.\$1AJN*O*")&H!#]+9 MP[(W\:E"!3!@YCK!7E^L460`/+"^8'@X
M`"@7-R S<4>B*3 @,'A#RQQ@U!(U,"!!8SWC6-#[!O"UQ"+"+YR11B([0@4P
MZSX1!< B+3)F@=$(< >0]V/0JY Z`6T$`3)!MA^7/[^80XH3%9"D(#)"3%@G
M0QC_/-&/XSJG$? VX"/V2]&AH6LX`+]A9@MP /&*P
M4YY2LB'_RK,&\,[P.O(S4 6@OV"Q@?\^,-^6!W,]10M@24'CUTD1?0(P:#S2
MO5%YD(DAB6)EX]V!,U!&05',L=_A5Q'OIA4)P./A-X!BSR'983?Q_SH5R8$-
ML$%Q1H$[`3\0Y\'_2\) L 5 0O W@$3 B?$]@/^)8M^6C_(+@ (0F%3GP3> 
M_ST`1)&>4T+P,T#-H N V:9_IA4>Z/'O\O_T#C.LUN-Y_PA@1+ )X$XQZP'N
M@^QB/7+_"X"XX3^RHL$\H.9#]D%2Y/\\8@# 5M#ME\9EI(")P"81?[520RCX
M=-Y!]N-$(N'!9/].-,S'IA4%H VP2\+Y%I:]?"\O.@#W_^WT,WBXY""F2%W0
M:E%.0T$0: %2_E\S<6Q6`+<&'PR>>!HP#<0
M#Y!,-X ?$4)?004=8TEGHD%02?<.\&WH6=!LI%"G$&:0`_PST.(W@$17A=!F
MT&1W#E*>`3YP-X!,4%9/XX60`1 J;' 7,#>BD3#\*B]H3QH!!(=YT18'7C3_
M`2& D#I1Z(+50>UW&:A](H<7%GW",W%?4%)/!%"84U-?:G!J8$-(&0;W&@$9
MBAWE(6JQ"W(,UVMT_B@0*C> %@=L,"$+&@&:)-\H$&Q6(+)?;27X,3B!`1+_
M8?"F%E]OV^-$D>QB1E*R(?YASO")$+D'Z]$]5#RA2Y+_W&*]\3FFXY#Y$T^7
M1@F8Z/_](\RI`#T9BAOR[''[[4O"_^X#/*$W@4O@^2)->+[#S*+M3Z!D&:@#
MZ4^!4!AA>='W:K0884-C2/B#>T$;ZT,Q_TO0OQ(9J&JQ=A Z;@2';$?[&:A8
M8'EW%&2A=V<:`4$Q_WK/'6D]CSZ3.81>)0$A/%2?S=/G\?AT*9^CI517[R%_
MZ6"TP.:!Y<$"5E6'#7%(^%532\KBL7(P)(D1V_7@5D,T+C#P;3KPIA4%*A$`
M3R #`! 0``````,`$1 `````0 `',!!6V(=(/KL!0 `(,!!6V(=(/KL!'@`]
;``$````%````4D4Z( `````#``TT_3<``.0;
`
end





| Вернуться в корень Архива |