Remove the obsolete Winelib HOWTO and DDE status.
This commit is contained in:
parent
c775bed4eb
commit
4db578fa72
|
@ -1,617 +0,0 @@
|
|||
WineLib HOWTO
|
||||
Version 28-Dec-2000
|
||||
|
||||
AUTHOR:
|
||||
Wilbur Dale
|
||||
Lumin Software BV
|
||||
Zandheuvel 52 B
|
||||
4901 HW Oosterhout (NB)
|
||||
The Netherlands
|
||||
|
||||
wilbur.dale@lumin.nl
|
||||
|
||||
WARNING: This HOWTO is incomplete. I expect to add to it on a weekly
|
||||
basis until it is complete.
|
||||
|
||||
=====================================================================
|
||||
|
||||
Table of Contents
|
||||
|
||||
I. Introduction: Wine vs. WineLib
|
||||
|
||||
IV. File Format Conversion
|
||||
|
||||
V. Compiling A Simple Win32 Program
|
||||
|
||||
VII. DLLs
|
||||
A. Windows executable and Windows DLL.
|
||||
B. Windows executable and WineLib DLL.
|
||||
C. WineLib executable and Windows DLL.
|
||||
D. WineLib executable and WineLib DLL.
|
||||
|
||||
VIII. How to use MFC
|
||||
A. Using a native MFC DLL
|
||||
B. Compiling MFC
|
||||
|
||||
=====================================================================
|
||||
|
||||
I. Introduction: Wine vs. WineLib
|
||||
|
||||
WineLib provides the Win32 API to a non-Microsoft operating
|
||||
system. The WineLib Win32 functions use X11 functions to perform the
|
||||
actual drawing on the screen. Wine and WineLib are based on the same
|
||||
set of functions that implement the Win32 API. The difference between
|
||||
Wine and WineLib is the type of executable that is loaded into memory
|
||||
and executed. If an executable and any associated DLLs were compiled
|
||||
for x86 hardware running the Windows 95, 98, or Windows NT (TM)
|
||||
operating systems, then Wine can use a special binary loader to load
|
||||
the program and the libraries into memory and execute it. WineLib on
|
||||
the other hand allows you to take the source for such a program and
|
||||
DLLs and compile it into the native format of a x86 Unix or Linux
|
||||
operating system. WineLib also allows you to partially compile the
|
||||
program and DLLs into the native format. For example, if you use a DLL
|
||||
from a vendor to provide some functions to your program and the vendor
|
||||
does not give you source, then you can use the Windows version of the
|
||||
DLL to provide the functions and compile the rest of your program in
|
||||
the native form for your system. [1]
|
||||
|
||||
Windows compilers and linkers generate executables with a different
|
||||
structure than standard compilers. Windows has two executable formats:
|
||||
the NE format and the PE format. The NE executable format provides for
|
||||
two entry points and the PE format provides for three entry points
|
||||
while a standard executable has a single entry point. Usually, a NE or
|
||||
a PE executable will use one of the entry points for your program and
|
||||
the other entry points will print an error message and exit. However,
|
||||
a linker can link 16 bit objects into one or both of the alternate
|
||||
entry points of a NE or PE executable.
|
||||
|
||||
Standard compilers assume that the function main() exists. The entry
|
||||
point for a standard program is constructed from the C runtime
|
||||
library, initialization code for static variables in your program, the
|
||||
initialization code for your classes (C++), and your function main().
|
||||
On the other hand, windows compilers assume WinMain() exists. The
|
||||
entry point for a windows program is constructed from the C runtime
|
||||
library, initialization code for static variables in your program, the
|
||||
initialization code for your classes (C++), and your function
|
||||
WinMain(). [4]
|
||||
|
||||
Since main() and WinMain() have different type signatures (parameter
|
||||
types), WineLib provides certain aids to generate code so that your
|
||||
program can be compiled and run as written for windows. For example,
|
||||
WineLib generates a main() to initialize the windows API, to load any
|
||||
necessary DLLs and then call your WinMain(). Therefore, you need to
|
||||
learn four basic operations to compile a windows program using
|
||||
WineLib: compiling a simple program, compiling resources, compiling
|
||||
libraries, and compiling MFC (if you will be using MFC). Each of these
|
||||
skills or operations are explained in later sections of this HOWTO.
|
||||
|
||||
Before you start porting your windows code to WineLib, you need to
|
||||
consider whether you are allowed to port your program to WineLib. As
|
||||
you compile your program using WineLib, you will be combining software
|
||||
from several sources and you need to ensure that the licenses for the
|
||||
components are compatible. Hence, in the next section, we will examine
|
||||
several legal issues.
|
||||
|
||||
|
||||
IV. File Format Conversion
|
||||
|
||||
Before you can compile your program, you must deal with one major
|
||||
difference between Windows and WineLib. Window sources are in DOS
|
||||
format with carriage return / line feed at the end of each line of
|
||||
text while WineLib files are in Unix format with only line feed at the
|
||||
end of each line of text.
|
||||
|
||||
The main problem with the difference between Unix and DOS format
|
||||
source files occurs with macro line continuation. A Unix compiler
|
||||
expects a backslash (\) followed by a newline (^J) to indict that a
|
||||
macro is continued on the next line. However, a file in DOS format will
|
||||
have the characters backslash (\), carriage return (^M), and newline
|
||||
(^J). The Unix compiler will interpret the backslash (\), carriage
|
||||
return (^M), newline (^) of a file in DOS format as a quoted carriage
|
||||
return and newline. The Unix compiler will think the line has ended
|
||||
and the macro is completely defined. Hence, before you compile your
|
||||
sources, you will need to convert you DOS format sources to Unix
|
||||
format. There are several tools such as dos2unix and tr that are
|
||||
available to convert the format.
|
||||
|
||||
FIXME: get more info on dos2unix, tr, and all other such tools and
|
||||
give example commands. Until I do [3] is a good source.
|
||||
|
||||
FIXME: is CR/LF conversion necessary for gcc 2.95 ?
|
||||
|
||||
V. Compiling A Simple Win32 Program
|
||||
|
||||
Wine and WineLib are written in C as is the MS Win32 API; thus, if
|
||||
have a program that calls only the Win32 API directly, you can compile
|
||||
the program using a C compiler and link it with some of the WineLib
|
||||
libraries. There are several simple examples of WineLib programs in
|
||||
the directory libtest/ in the Wine source tree. We shall examine one
|
||||
of these to show you how to compile a WineLib program.
|
||||
|
||||
The example we shall examine is hello2. If you examine hello2.c, you
|
||||
will see it is a windows program that pops up a message box that says
|
||||
"Hello, hello!". It can be compiled and run using a windows compiler
|
||||
just like any other windows program. However, it can not be compiled
|
||||
and run with a non-windows compiler. As mentioned previously, windows
|
||||
programs have an entry point called WinMain(), while non-windows
|
||||
compilers use an entry point of main(). Hence, we need some "glue" to
|
||||
glue the main() entry point to the WinMain() in the windows program.
|
||||
|
||||
In WineLib, some of the glue is provided by the spec file. Spec files
|
||||
are used in several places in Wine and WineLib to provide glue between
|
||||
windows code and code for non-windows compilers. WineLib provides a
|
||||
tool called winebuild in the tools/winebuild directory that converts a
|
||||
spec file into a C file that can be compiled and linked with the
|
||||
windows source files. ...
|
||||
|
||||
VII. DLLs
|
||||
|
||||
As mentioned in the introduction, Wine allows you to execute windows
|
||||
executables and windows libraries under non-Microsoft operating
|
||||
systems. WineLib allows you to take sources intended for the windows
|
||||
operating system and to compile them to run as native executables
|
||||
under a Unix/Linux operating system. With an executable and a single
|
||||
library, there are four combinations in which to run the programs and
|
||||
the library:
|
||||
1. a Windows executable with a Windows DLL,
|
||||
2. a Windows executable with WineLib DLL,
|
||||
3. a WineLib executable with Windows DLL, and
|
||||
4. a WineLib executable with WineLib DLL.
|
||||
In this section, we will discuss each of these and discuss the steps
|
||||
required to implement the executable/DLL combination.
|
||||
|
||||
A. Windows executable and Windows DLL
|
||||
|
||||
Running a windows executable with a windows DLL is not a WineLib
|
||||
program: it is a Wine program. If you type
|
||||
wine program.exe
|
||||
and the DLL is in the search path, then the windows program should run
|
||||
using the windows DLL.
|
||||
|
||||
FIXME: find out what is the search path.
|
||||
|
||||
B. Windows executable and WineLib DLL
|
||||
|
||||
Running a windows executable with a WineLib DLL is also accomplished
|
||||
using the Wine program. The source code for the DLL is compiled into a
|
||||
Unix style shared library. When the windows executable "loads" the
|
||||
DLL, Wine will use the shared library (.so file) instead.
|
||||
|
||||
At first you may wonder why you would want to run a windows executable
|
||||
with a WineLib DLL. Such a situation implies you do not have the
|
||||
source for the executable, but you do have the source for the
|
||||
DLL. This is backwards from what you might expect. However, I do have
|
||||
an example where this situation might arise.
|
||||
|
||||
Codewright is a popular editor in the windows world, and the
|
||||
capabilities of Codewright can be extended by using DLLs. Since
|
||||
Codewright is a commercial product, you do not have the source and
|
||||
must use the windows executable with Wine. If you have written a DLL
|
||||
to add functionality to Codewright, you have two choices: you can
|
||||
compile the DLL using a windows compiler and use both a windows
|
||||
executable and a windows DLL as in case A above, or you can use
|
||||
WineLib and compile the DLL as a shared library (.so file). I have no
|
||||
idea if Codewright actually runs under Wine, but this is an example of
|
||||
why you might decide to use a windows executable and a WineLib
|
||||
DLL. Many other editors and other programs use DLLs to extend their
|
||||
functionality.
|
||||
|
||||
In order for Wine to use the WineLib DLL, certain glue code is need to
|
||||
replace the linker magic that windows compilers use. As with a simple
|
||||
executable, the winebuild program uses a spec file to generate the glue
|
||||
code. For example, in the spec file for the DLL will look something like
|
||||
name winedll
|
||||
type win32
|
||||
init winedll_DllMain
|
||||
1 cdecl _WINEbirthDay@4 ( str ) WINEbirthDay
|
||||
2 cdecl _WINEfullName@4 ( str ) WINEfullName
|
||||
The name is the name of the DLL. Since WineLib only supports win32,
|
||||
the type should always be win32. The init function is the name of the
|
||||
initialization function for the DLL. The initialization function for a
|
||||
windows DLL is named DllMain(). You will need to rename the function
|
||||
in the DLL source so there will not be any name clashes with the
|
||||
DllMain() of other DLLs in you program.
|
||||
|
||||
The last two lines of the spec file above, provide the export
|
||||
information for the DLL. For example, the line
|
||||
1 cdecl _WINEbirthDay@4 ( str ) WINEbirthDay
|
||||
says that the function at ordinal 1 uses the cdecl calling convention
|
||||
for the parameters. The DLL export name is _WINEbirthDay@4. The
|
||||
function takes a single parameter that is a string. Finally, the C
|
||||
function name to be called whenever this DLL function is called is
|
||||
WINEbirthday. You will need a function ordinal line for each function
|
||||
in the DLL. The export name and the ordinal can be obtained from the
|
||||
windows program dumpbin and the windows version of the DLL. See the
|
||||
file <wine>/tools/winebuild/README for more details on the spec file
|
||||
format.
|
||||
|
||||
During the compile process, a command like
|
||||
winebuild -fPIC -o winedll.spec.c -spec winedll.spec
|
||||
will be executed to create the file winedll.spec.c from information in
|
||||
the file winedll.spec. The file winedll.spec.c and winedll.c are
|
||||
compiled into object files and used to create the shared library.
|
||||
|
||||
In order for the program to run, a copy of the shared library must be in
|
||||
your EXTRA_LD_LIBRARY_PATH. For example, if your wine.conf file has
|
||||
the following line,
|
||||
EXTRA_LD_LIBRARY_PATH=${HOME}/wine/lib
|
||||
then you must copy the shared library into the directory ~/wine/lib/
|
||||
and the shared library will now be in the correct search path.
|
||||
|
||||
Now when you type
|
||||
wine program.exe
|
||||
the program will load the shared library (.so).
|
||||
|
||||
C. WineLib executable and Windows DLL
|
||||
|
||||
Running a WineLib executable with a Windows DLL is accomplished
|
||||
using WineLib. This situation will be common since you may have
|
||||
purchased DLLs to use with you project and the DLL vendor may not give
|
||||
you the source code for the DLL.
|
||||
|
||||
In order for WineLib to use the Windows DLL, certain glue code is
|
||||
needed to replace the linker magic that windows compilers use. Part of
|
||||
the glue code must be written by you. The basic idea of the glue code
|
||||
is that you write a new DLL that consists of function pointers. Each
|
||||
function in the DLL will consist of a call on a function pointer. For
|
||||
example,
|
||||
WINEDLL_ConstString WINEDLL_INTERFACE
|
||||
WINEfullName( WINEDLL_ConstString handle ) {
|
||||
return (* pWINEfullName) ( handle );
|
||||
}
|
||||
The initialization function for the DLL will use the function
|
||||
LoadLibrary() to load the windows DLL and initialize the function
|
||||
pointers using the function GetProcAddress().
|
||||
|
||||
Since Wine can use either windows DLLs or Unix shared libraries (.so),
|
||||
the LoadLibrary() function call may have unexpected results if there
|
||||
is a winedll.dll and a winedll.so file. Hence, the windows version of
|
||||
the DLL should be named something like hiddenWinedll.dll and the
|
||||
shared library should be named winedll.so. Now the shared library will
|
||||
use LoadLibrary() to load the "hidden" DLL.
|
||||
|
||||
The shared library will need a spec file. Fortunately, it is simpler
|
||||
than case B above. The spec file will look something like
|
||||
name winedll
|
||||
type win32
|
||||
init winedll_DllMain
|
||||
The name is the name of the DLL. Since WineLib only supports win32,
|
||||
the type should always be win32. The init function is the name of the
|
||||
initialization function for the shared library. This is the function
|
||||
that will load the "hidden" DLL and initialize the function
|
||||
pointers. There is no need for any function ordinals unless your
|
||||
program calls functions by the ordinal.
|
||||
|
||||
During the compile process, a command like
|
||||
winebuild -fPIC -o winedll.spec.c -spec winedll.spec
|
||||
will be executed to create the file winedll.spec.c from information in
|
||||
the file winedll.spec. The file winedll.spec.c and winedll.c are
|
||||
compiled into object files and used to create the shared library.
|
||||
|
||||
Now that the shared library is compiled, you still need to compile
|
||||
your program. Part of the compile process for your program will
|
||||
consist of a spec file for your program. For example,
|
||||
name program
|
||||
mode guiexe
|
||||
type win32
|
||||
init WinMain
|
||||
import winedll.dll
|
||||
This spec file is similar to the spec file of the simple WineLib
|
||||
example in part V above. The only difference is the import
|
||||
specification that tells WineLib that the main program uses
|
||||
winedll.dll. If this import line is not included, the "hidden" DLL
|
||||
will not be loaded and the function pointers will not be initialized.
|
||||
|
||||
During the compile process, a command like
|
||||
winebuild -fPIC -o program.spec.c -spec program.spec
|
||||
will be executed to create the file program.spec.c from information in
|
||||
the file program.spec. The file program.spec.c and your source code are
|
||||
compiled into object files and used to create the executable.
|
||||
|
||||
D. WineLib executable and WineLib DLL.
|
||||
|
||||
Running a WineLib executable with a WineLib DLL is accomplished using
|
||||
WineLib. The source for the DLL will be combined with a spec file to
|
||||
generate the shared library. Likewise, the source for your program and
|
||||
a spec file will be combined to create the executable. In the source
|
||||
for the DLL, you should change the name of DllMain() to a name like
|
||||
winedll_DllMain() so that there will not be a name clash with other
|
||||
initialization functions for other DLLs.
|
||||
|
||||
The shared library's spec file is like case C above. The spec file
|
||||
will look something like
|
||||
name winedll
|
||||
type win32
|
||||
init winedll_DllMain
|
||||
The init function is the name of the initialization function for the
|
||||
shared library (what you renamed DllMain to). There is no need for any
|
||||
function ordinals unless your program calls functions by the ordinal.
|
||||
|
||||
During the compile process, a command like
|
||||
winebuild -fPIC -o winedll.spec.c -spec winedll.spec
|
||||
will be executed to create the file winedll.spec.c from information in
|
||||
the file winedll.spec. The file winedll.spec.c and the source code for
|
||||
your DLL are compiled into object files and used to create the shared
|
||||
library.
|
||||
|
||||
Compiling your program is exactly like case C above. For example, the
|
||||
spec file for you program will look something like
|
||||
name program
|
||||
mode guiexe
|
||||
type win32
|
||||
init WinMain
|
||||
import winedll.dll
|
||||
|
||||
During the compile process, a command like
|
||||
winebuild -fPIC -o program.spec.c -spec program.spec
|
||||
will be executed to create the file program.spec.c from information in
|
||||
the file program.spec. The file program.spec.c and your source code are
|
||||
compiled into object files and used to create the executable.
|
||||
|
||||
VIII. How to use MFC
|
||||
A. Using a native MFC DLL
|
||||
B. Compiling MFC
|
||||
|
||||
FIXME: to be continued.
|
||||
|
||||
A Windows compiler does NOT generate a fake main. Instead, the
|
||||
executable file format provides for 2 (NE) or 3 (PE) entry points.
|
||||
One of these is your program, the other(s) are normally filled with
|
||||
stubs that print an error message and exit. It is possible to instruct
|
||||
the _linker_ to link 16-bit objects into one or both of the alternate
|
||||
entry points, and create a fat binary.
|
||||
|
||||
At the C/C++ level, your statement about WinMain() is correct. Of
|
||||
course the actual entry point first inits run time lib etc, and then
|
||||
calls the C/C++ level entry, but that is also true for main() in the
|
||||
standard setup. It may be important to regurgitate this info here,
|
||||
though, because some of the fun things that can happen with multiple
|
||||
run time libs and DLLs occur at this level.
|
||||
|
||||
Line 86: I only need to know how compile MFC if I use it... :-)
|
||||
|
||||
|
||||
From: Damyan Ognyanoff <Damyan@rocketmail.com>
|
||||
Subject: Re: Wine MFC info request
|
||||
|
||||
hi,
|
||||
my MFC is from VC6.0 with SP3
|
||||
MFC Bulid: (form afxbld_.h)
|
||||
#define _MFC_BUILD 8447
|
||||
#define _MFC_USER_BUILD "8447"
|
||||
#define _MFC_RBLD 0
|
||||
mfcdll.rc
|
||||
FILEVERSION 6,0,_MFC_BUILD,_MFC_RBLD
|
||||
PRODUCTVERSION 6,0,0,0
|
||||
|
||||
Hints:
|
||||
1. Wine include files
|
||||
|
||||
In some of them you will find error about '__attribute__' all kinds of
|
||||
similar errors can be fixed using proper typedefs first example :
|
||||
|
||||
typedef BOOL (CALLBACK *DLGPROC)(HWND,UINT,WPARAM,LPARAM);
|
||||
|
||||
must be converted to
|
||||
|
||||
typedef BOOL CALLBACK (*DLGPROC)(HWND,UINT,WPARAM,LPARAM);
|
||||
|
||||
and the second kind is something like
|
||||
|
||||
TYPE* WINAPI SomeFunction(HWND param1,UINT param2);
|
||||
|
||||
The problem here is a TYPE* or TYPE& (in some of mfc files) the
|
||||
workaround is to declare a type before:
|
||||
|
||||
typedef TYPE* TYPEPtr;
|
||||
|
||||
or
|
||||
|
||||
typedef TYPE& TYPERef;
|
||||
|
||||
and declaration will look like:
|
||||
|
||||
TYPEPtr WINAPI SomeFunction(HWND param1,UINT param2);
|
||||
|
||||
note: don't miss a 'struct' when you define struct type pointers. I
|
||||
miss it and get a lot of problems compiling MFC:
|
||||
|
||||
>>
|
||||
struct _TEB;
|
||||
typedef !!!struct!!! _TEB* P_TEB;
|
||||
extern inline P_TEB WINAPI NtCurrentTeb(void);
|
||||
<<
|
||||
|
||||
Those conversions are semantically the same as above but g++ compile
|
||||
them and generate proper code to invoke __stdcall kind of functions
|
||||
|
||||
in some of Wine/obj_XXX.h files: Wine/obj_base.h - there are a lot of
|
||||
defines's that are used to declare a COM interfaces
|
||||
|
||||
#define ICOM_METHOD(ret,xfn) \
|
||||
public: virtual ret (CALLBACK xfn)(void) = 0;
|
||||
|
||||
will be (for all of them that are related to C++ (watch #ifdef's
|
||||
carefully)):
|
||||
|
||||
#define ICOM_METHOD(ret,xfn) \
|
||||
public: virtual ret CALLBACK (xfn)(void) = 0;
|
||||
|
||||
and the second tip is an error when compiler stops on line like:
|
||||
|
||||
ICOM_DEFINE(ISomeInterfase,IUnknown)
|
||||
|
||||
watch method declarations above to find something like:
|
||||
|
||||
ICOM_METHOD1(TYPE*,MethodName, DWORD,dwParam)
|
||||
|
||||
and replace TYPE* with proper TYPEPtr type. In many cases You will see
|
||||
void* which can be replaced simply by LPVOID.
|
||||
|
||||
qthere are several errors related to anonymous structs and unions but
|
||||
they can be avoided with proper - #ifdef __cplusplus
|
||||
|
||||
This is all about Wine headers I think. If you find something that I
|
||||
miss type a line of mail to me.
|
||||
|
||||
2. MFC
|
||||
The rules are the same with some new issues:
|
||||
|
||||
virtual BOOL Method1(int param1, BOOL (CALLBACK *param2)
|
||||
(HWND,UINT,WPARAM,LPARAM));
|
||||
|
||||
don't compile. I remove a function pointer declaration
|
||||
outside method:
|
||||
|
||||
typedef BOOL CALLBACK
|
||||
(*param2Type)(HWND,UINT,WPARAM,LPARAM);
|
||||
|
||||
virtual BOOL Method1(int param1, param2Type param2);
|
||||
|
||||
I didn't apply this technique to a operator new
|
||||
definitions:
|
||||
|
||||
void* AFXAPI operator new(size_t nSize);
|
||||
|
||||
so i remove AFXAPI from these declarations:
|
||||
|
||||
I got some missed #defines from commctrl.h and I added
|
||||
them form VC6.0 include.
|
||||
|
||||
these are my defines form Makefile which I used to
|
||||
compile MFC
|
||||
|
||||
-DTWINE_NO_CMONIKER \ -- this is related to exclude
|
||||
CMonikerFile
|
||||
-D__urlmon_h__ \ -- Wine didn't have URL interfaces
|
||||
-D_AFX_NO_OLEDB_SUPPORT \
|
||||
-D_WIN32 \
|
||||
-DNOWIN98 \ -- this is used to exclude all
|
||||
unimplemented classes from commctrl
|
||||
-D_AFX_PACKING \
|
||||
-D_AFX_NO_DHTML_SUPPORT \
|
||||
-D_AFX_NO_SOCKET_SUPPORT \
|
||||
-D_AFX_NO_SYNC_SUPPORT \
|
||||
-D_AFX_NO_OCX_SUPPORT \
|
||||
-D_AFX_PORTABLE \
|
||||
-D_AFX_OLD_EXCEPTIONS \
|
||||
-D_AFX_NO_SOCKET_SUPPORT \
|
||||
-D_AFX_NO_DEBUG_CRT \
|
||||
-D_AFX_NO_DAO_SUPPORT \
|
||||
-D_AFX_NO_OCC_SUPPORT \
|
||||
-D_AFX_NO_INET_SUPPORT \
|
||||
-D_AFX_NO_RICHEDIT_SUPPORT \
|
||||
-D_X86_ \
|
||||
-DLONGHANDLES
|
||||
|
||||
may be you will try to enable some of features of mfc I tested only
|
||||
-D_AFX_NO_OCC_SUPPORT but got missing interfaces from Wine
|
||||
|
||||
in file afxcom_.h
|
||||
- _CIP<_Interface, _IID>::~_CIP<_Interface, _IID>()
|
||||
+ _CIP<_Interface, _IID>::~_CIP()
|
||||
|
||||
in file afxtempl.h
|
||||
- BOOL Lookup(BASE_CLASS::BASE_ARG_KEY key,
|
||||
VALUE& rValue) const
|
||||
- { return BASE_CLASS::Lookup(key,
|
||||
(BASE_CLASS::BASE_VALUE&)rValue); }
|
||||
+ BOOL Lookup(typename BASE_CLASS::BASE_ARG_KEY
|
||||
key, VALUE& rValue) const
|
||||
+ { return BASE_CLASS::Lookup(key,
|
||||
(typename BASE_CLASS::BASE_VALUE&)rValue); }
|
||||
|
||||
and all releated errors can be fixed in this way.
|
||||
|
||||
3. spec file
|
||||
name mfc42
|
||||
type win32
|
||||
rsrc mfc42
|
||||
|
||||
10 stdcall WinMain(long long ptr long) WinMain
|
||||
|
||||
4. linking
|
||||
use -rdynamic wnen link libmfc.so to get ARGV and
|
||||
ARGC from loader
|
||||
|
||||
5. I didn'n build a extension dll with Wine but I suspect that there
|
||||
will be some problems related to a chaining Runtime classes form MFC
|
||||
to a new dll
|
||||
|
||||
6. build your app as a MODULE too.
|
||||
|
||||
7. make a loader and in it's _WinMain:
|
||||
... includes are here
|
||||
iint PASCAL (*winMain)(HINSTANCE,HINSTANCE,LPSTR,int) =
|
||||
0;
|
||||
my app uses these to manage filenames
|
||||
VOID __cdecl (*_splitpath1)(LPCSTR path, LPSTR drive,
|
||||
LPSTR directory, LPSTR filename, LPSTR extension ) =
|
||||
NULL;
|
||||
VOID __cdecl _splitpath(LPCSTR path, LPSTR drive,
|
||||
LPSTR directory, LPSTR filename, LPSTR extension )
|
||||
{
|
||||
if (_splitpath1)
|
||||
_splitpath1(path, drive, directory, filename,
|
||||
extension );
|
||||
}
|
||||
VOID __cdecl (*_makepath1)(LPSTR path, LPCSTR drive,
|
||||
LPCSTR directory, LPCSTR filename, LPCSTR extension )
|
||||
= NULL;
|
||||
VOID __cdecl _makepath(LPSTR path, LPCSTR drive,
|
||||
LPCSTR directory, LPCSTR filename, LPCSTR extension )
|
||||
{
|
||||
if (_makepath1)
|
||||
_makepath1(path, drive, directory, filename,
|
||||
extension);
|
||||
}
|
||||
int PASCAL _WinMain(HINSTANCE h,HINSTANCE h1,LPSTR
|
||||
lpszCmdParam,int c)
|
||||
{
|
||||
HINSTANCE hInstance,hins,hlib,htst,hform,himag,hexe;
|
||||
int retv;
|
||||
|
||||
hins = LoadLibrary("CRTDLL.DLL");
|
||||
_splitpath1 = GetProcAddress(hins,
|
||||
"_splitpath");
|
||||
_makepath1 = GetProcAddress(hins,
|
||||
"_makepath");
|
||||
hins = LoadLibrary("COMCTL32.DLL");
|
||||
hins = LoadLibrary("COMDLG32.DLL");
|
||||
|
||||
|
||||
hins = dlopen("libmfc42.so",2);
|
||||
hlib = LoadLibrary("mfc42");
|
||||
himag = dlopen("libmxformatslib.so",2);
|
||||
hform = LoadLibrary("mxformatslib");
|
||||
hexe = dlopen("libmxpaint.so",2);
|
||||
htst = LoadLibrary("mxpaint");
|
||||
|
||||
winMain = GetProcAddress(hlib, "WinMain");
|
||||
if (winMain)
|
||||
{
|
||||
retv = winMain (htst, // note the > htst
|
||||
< HERE
|
||||
0,
|
||||
lpszCmdParam,
|
||||
SW_NORMAL);
|
||||
}
|
||||
FreeLibrary(htst);
|
||||
FreeLibrary(hform);
|
||||
FreeLibrary(hlib);
|
||||
dlclose(hexe);
|
||||
dlclose(himag);
|
||||
dlclose(hins);
|
||||
return retv;
|
||||
}
|
||||
the spec for loader is:
|
||||
name c10
|
||||
mode guiexe
|
||||
type win32
|
||||
init _WinMain
|
||||
|
||||
please find attached a Makefile which i use to build
|
||||
MFC
|
||||
|
||||
Regards
|
||||
Damyan.
|
|
@ -1,50 +0,0 @@
|
|||
This is the status for DDE (i.e. raw dde messages) and ddeml.
|
||||
|
||||
DDE was implemented by Micheal Veksler some time ago, it has been reported as broken
|
||||
by changes in the server and related parts of wine. AFAIK no-one has tried to fix these
|
||||
and I have not tried to test them.
|
||||
|
||||
ddeml was untouched until December 1998 when some of the Corel/Macadamian team started
|
||||
writing bits that were needed by Corel for the WordPerfect Suite port. These were mainly
|
||||
around string handling and have been identified in the change history for each routine.
|
||||
They were written to cope with a single instance only. About a week later I started
|
||||
looking at ddeml as a whole.
|
||||
|
||||
The initialisation was tackled first, then the routines produced by Corel/Macadamian
|
||||
were modified to cope with multiple instances of dde client/server and a first cut at
|
||||
the un-initialise routine.
|
||||
|
||||
DdeNameService has now been produced as a first-cut routine, but the monitor notification
|
||||
must be tackled, followed by the main message reception routine and the invoking of the
|
||||
callback. Serious testing from this point may well depend on Wine thread handling
|
||||
settling down.
|
||||
|
||||
The strategy so far has been to tackle the Unicode versions first. Once they have been
|
||||
accepted as close to complete then the 32-bit ASCII routines then the 16-bit routines.
|
||||
|
||||
It is recognised that the solutions adopted may well not be suitable for wine-OS2, since
|
||||
that OS has its own DDE rotuines intermediate in integration between raw DDE and ddeml,
|
||||
also O/S 2 users may well want programs running under Wine to talk to native O/S 2 programs.
|
||||
I do not have knowledge of MacOS or the internals of BeOS, but these may suffer from the
|
||||
same problems.
|
||||
|
||||
TO DO
|
||||
|
||||
Complete initialisation, some of the 2nd call validation conditions have not been worked out
|
||||
yet and the code for enabling the message loop needs writing.
|
||||
|
||||
Complete initialize and unitialize, also add the callback handling to DdeNameService.
|
||||
|
||||
Add true Unicode handling to CreateStringHandle, QueryString, CmpStringHandles. Also find
|
||||
out why Initialize needs ASCII and Unicode variants.
|
||||
|
||||
Add DdeGetLAstError and related handling in all other modules. Also find out what to do about
|
||||
storing errors that result in the instance failing to initialise in some way.
|
||||
|
||||
|
||||
Just about all the rest
|
||||
|
||||
More specific items are commented in the code.
|
||||
|
||||
|
||||
Keith Matthews
|
Loading…
Reference in New Issue