Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

LoadLibrary behaves strangely on Win98

Posted on 2002-07-29
20
Medium Priority
?
299 Views
Last Modified: 2013-11-20
I have an MFC program that should run on W2K, NT, and 98.
The program uses features that exist in the RichEdit control version 2 & 3, that are in riched20.dll.

MFC calls LoadLibraryA("RICHED32.DLL") .
In W2K it works great because the riched32.dll there, is actually an emulator that runs version 2 from riched20.

In NT it doesn't work naively, but I solved the problem by copying the riched32.dll emulator to the same folder where my executables reside. Since LoadLibrary uses a normal directory search algorithm, this riched32.dll is loaded (and not the one from the Windows\System32 directory) and everything again works OK.

In Win 98, I tried the same trick as in NT but it doesn't work. The riched32.dll loaded is always the one from the Windows\system directory, no matter how I play with the PATH. Replacing riched32.dll solves the problem, but that is something I do not want to do on a user's PC because I am changing the system.

How can I get LoadLibrary to take the DLL from the application executable directory (as is documented)?
Alternatively , how else can I resolve the problem?
0
Comment
Question by:mco
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 9
  • 6
  • 5
20 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 7185109
>>How can I get LoadLibrary to take the DLL from the application executable directory (as is documented)?


Use a fully qualified path, e.g.

char acPath [ MAX_PATH];

GetModuleFileName ( NULL, acPath, MAX_PATH);

PathRemoveFileSpec ( acPath);

lstrcat ( acPath, "\\dllname.dll");

HINSTANCE hDll = LoadLibrary ( acPath);
0
 
LVL 1

Author Comment

by:mco
ID: 7185118
Sorry, I should have stressed the following point: I do not intend to modify MFC source code. It is a maintenance hell.
0
 
LVL 86

Expert Comment

by:jkr
ID: 7185129
>>I do not intend to modify MFC source code

Why should you?
0
Learn how to optimize MySQL for your business need

With the increasing importance of apps & networks in both business & personal interconnections, perfor. has become one of the key metrics of successful communication. This ebook is a hands-on business-case-driven guide to understanding MySQL query parameter tuning & database perf

 
LVL 1

Author Comment

by:mco
ID: 7185156
As I said, the call LoadLibraryA("RICHED32.DLL") , is made from MFC source. That is not my code.
0
 
LVL 86

Expert Comment

by:jkr
ID: 7185161
BTW, there's another point -however, so far I was not able to locate the article on MSDN again, so just a quote here:

"There's also a new approach called 'Private DLLs', see http://msdn.microsoft.com/library/techart/dlldanger1.htm :
Private DLLs are also referred to as side-by-side DLLs, because a private copy of a DLL is used in one
specific application while the system DLL is used by other applications. If you run WordPad and SuperApp
concurrently, two copies of Msvcrt.dll are loaded into memory (hence, the "side-by-side" terminology),
even if WordPad and SuperApp use the same version of Msvcrt.dll.
There are two approaches to implementing private DLLs. If you're writing a new application or a new
component, you give each version a unique version number. You then register each DLL or component in
the application directory where you want a private copy. Your application knows to load a private copy
of a shared DLL by version information in the application.
The second side-by-side approach is geared toward existing applications. Suppose C:\SuperApp\SuperApp.exe
is an existing application that you want to protect from future DLL upgrades or was broken by a service
pack upgrade. You simply copy the DLLs you want private to SuperApp into .\SuperApp and create an empty
file in this directory called ".\SuperApp.exe.local." Now when SuperApp fires up and finds the .local
file it searches the current directory for DLLs and COM servers before it searches the standard path.
If your application is broken by a service pack upgrade, you create an install program with the .local
file and the older DLLs you need and provide them to your customers."
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 7185163
I agree with jkr ... do something like this instead of calling
AfxInitRichEdit(), i.e. in InitInstance of your app:

extern _AFX_RICHEDIT_STATE* AFX_CDECL AfxGetRichEditState();

_AFX_RICHEDIT_STATE* pState = AfxGetRichEditState();
ASSERT (pState->m_hInstRichEdit == NULL); // to ensure it's not already loaded.
// create path as in jkr's post
...
pState->m_hInstRichEdit = LoadLibrary(<thePathToDLL>);


ZOPPO
0
 
LVL 1

Author Comment

by:mco
ID: 7185210
Zoppo,
Actually, writing my own version of AfxInitRichEdit was my first attempt , but I failed even to compile. Did you manage to compile your suggestion?

The code:
#include "afxrich.h"
.
.
.
BOOL CREApp::InitInstance()
{
_AFX_RICHEDIT_STATE* pState = AfxGetRichEditState();
pState->m_hInstRichEdit = 99;

I get an error: error C2027: use of undefined type '_AFX_RICHEDIT_STATE' , on the last line above.
I.e. there is no error on the line where pState is declared and assigned, although the same type is used, but
there is an error on the last line where a field of pState is accessed.
0
 
LVL 86

Expert Comment

by:jkr
ID: 7185224
>>error C2027: use of undefined type '_AFX_RICHEDIT_STATE'

You do

#include <afxrich.h>

?
0
 
LVL 31

Accepted Solution

by:
Zoppo earned 1200 total points
ID: 7185234
hmm ... I found _AFX_RICHEDIT_STATE declare in <afximpl.h>, so

#include <../src/afximpl.h>

solved the compiler errors here.
0
 
LVL 1

Author Comment

by:mco
ID: 7186375
I'll try it out soon.
Are there any pitfalls with including an *impl.h file?
I thought they were only for building MFC, not for applications linking with it.
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 7187285
>Are there any pitfalls with including an *impl.h file?

Well, I'm not absoluteley sure, but I found some articles in MSDN where <afximpl.h> is included to workaround known
problems, i.e. http://support.microsoft.com/default.aspx?scid=kb;[LN];Q230377

ZOPPO
0
 
LVL 1

Author Comment

by:mco
ID: 7187382
Zoppo,
I am going to give you an A because you solved the problem.
For the record, there is a more elegant method that does not require including an internal MFC file: If I just pre-load the desired riched32.dll before calling MFC's original AfxInitiRichEdit, then the load in MFC will not load a different version. It will use the one I have preloaded.
0
 
LVL 86

Expert Comment

by:jkr
ID: 7187808
So, using the full path had nothing to do with the solution?
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 7187819
Maybe solution was a co-production ... if you want I can offer you half of the points, ok?
0
 
LVL 1

Author Comment

by:mco
ID: 7187825
No need. I posted the same question in the W98 topic area and a person there gave the preloading idea and he got full points.
0
 
LVL 1

Author Comment

by:mco
ID: 7187834
jkr, of course the full path is needed, but that was not part of the problem. (I knew how to get the fullpath but had  a problem getting MFC to load from there).
0
 
LVL 31

Expert Comment

by:Zoppo
ID: 7187836
> jkr, of course the full path is needed, but that was not part of the problem.

Well, sorry, but I don't agree ... the main problem was that
the full path was needed ... how to load the riched20.dll from
a given path was a secondary problem then ...

Therefore I asked jkr whether he agrees if I offer him half of the points.
0
 
LVL 1

Author Comment

by:mco
ID: 7187855
1) It is up to you, they are your points and you can do whatever you want with them :-)
2) I am just stating that loading with the full path was not the problem I presented. The problem I presented was that I did not know how to change which DLL MFC will load on a Win98 OS. It is correct that in the solution you also need to load the full path, but you also need to do other things.
Your reply by itself without jkr's, solved the problem.
0
 
LVL 86

Expert Comment

by:jkr
ID: 7188064
>>Your reply by itself without jkr's, solved the problem.

The reply was "I agree with jkr"

*shrug*

Have a nice time on EE.
0
 
LVL 1

Author Comment

by:mco
ID: 7188098
Look, I also agree with you, jkr. Your posting was correct.
I think though, that points should go to whoever helps solve the problem that was posted, not necessarily to everyone writing truthful information.
Again, the problem I posed was of getting MFC to load the correct DLL, not on loading a specific DLL in general.
0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
If you use Adobe Reader X it is possible you can't open OLE PDF documents in the standard. The reason is the 'save box mode' in adobe reader X. Many people think the protected Mode of adobe reader x is only to stop the write access. But this fe…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
Have you created a query with information for a calendar? ... and then, abra-cadabra, the calendar is done?! I am going to show you how to make that happen. Visualize your data!  ... really see it To use the code to create a calendar from a q…

660 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question