�������� Linux Tags

21. ��̬�����ʽ��

��̬�����ʽ�⣨Ҳ��ΪDLL����Microsoft Windows����Ҫ�����Ҫ��֮һ���������Windows��صĴŵ�����������dz�ʽģ�飬���Ƕ�̬�����ʽ������Ϊֹ�����Ƕ����ڿ���WindowsӦ�ó�ʽ�������dz��Ա�д��̬�����ʽ���ʱ���ˡ��������Ѿ�ѧ��ı�дӦ�ó�ʽ�Ĺ���ͬ������춱�д��Щ��̬�����ʽ��ģ�飬��Ҳ��һЩ��Ҫ�IJ�ͬ��

��̬�����ʽ��Ļ���֪ʶ
��

����ǰ���������ģ�WindowsӦ�ó�ʽ��һ����ִ�е�������ͨ������һ���򼸸��Ӵ�����ʹ��ѶϢ��Ȧ����ʹ�������롣ͨ������̬�����ʽ�Ⲣ����ֱ��ִ�У�Ҳ������ѶϢ��������һЩ�����ĵ��������а����ܱ���ʽ������DLL���������һ����ҵ�ĺ�ʽ��ֻ��������ģ����ж�̬�����ʽ���еĺ�ʽʱ�����ŷ������á�

��ν����̬���᡹����ָWindows��һ��ģ���еĺ�ʽ�������ᵽ��̬�����ʽ��ģ���е�ʵ�ʺ�ʽ�ϵij����ڳ�ʽ�����У���������Ŀ��ģ��(.OBJ)��ִ��ʱ�ڳ�ʽ��(.LIB)�������Լ��������ѱ������Դ(.RES)����������һ���Ա㽨��Windows��.EXE��������ʱ�������ǡ���̬���᡹����̬������˲�ͬ����������ִ��ʱ�ڡ�

KERNEL32.DLL��USER32.DLL��GDI32.DLL������������ʽ������KEYBOARD.DRV��SYSTEM.DRV��MOUSE.DRV����Ѷ��ӡ����������ʽ���Ƕ�̬�����ʽ�⡣��Щ��̬�����ʽ���ܱ�����WindowsӦ�ó�ʽʹ�á�

��Щ��̬�����ʽ�⣨�����嵵���ȣ�����Ϊ������Դ��������ֻ�������ϣ�ͨ������Դ����ʽ������������ʽ�롣�ɴ˿ɼ�����̬�����ʽ���Ŀ��֮һ�����ṩ�ܱ����಻ͬ��Ӧ�ó�ʽ��ʹ�õĺ�ʽ����Դ����һ�����ҵϵͳ�У�ֻ����ҵϵͳ�����Ű�������Ӧ�ó�ʽ�ܹ����������ijһ��ҵ�ij�ʽ����Windows�У�һ��ģ�������һ��ģ�麯ʽ�ij����ƹ��ˡ����ʹ�ñ�дһ����̬�����ʽ�⣬Ҳ����������Windows����Ȼ��Ҳ����Ϊ��̬�����ʽ�⣨��������Windows����Щ��̬�����ʽ�ⳣʽ���Ƕ�ʹ���߳�ʽ�����䡣

����һ����̬�����ʽ��ģ���������������������.EXE��.FON��������׼��������.DLL��ֻ�д�.DLL�������Ķ�̬�����ʽ����ܱ�Windows�Զ����롣������������������������ʽ��������ʹ��LoadLibrary����LoadLibraryEx��ʽ�����ģ�顣

��ͨ���ᷢ�֣���̬�����ʽ���ڴ���Ӧ�ó�ʽ���������塣���磬����ҪΪWindows��дһ���ɼ�����ͬ�ij�ʽ��ɵĴ��Ͳ�����װ���壬�ͻᷢ����ЩӦ�ó�ʽ��ʹ�����๲ͬ�ij�ʽ�����԰���Щ������ʽ����һ��һ���Ե�Ŀ�����ʽ�⣨��.LIB���������У�����ʹ��LINK��̬����ʱ�����Ǽ������ʽģ���С������ַ����Ǻ��˷ѵģ���Ϊ��װ�����е�ÿ����ʽ�������빫����ʽ��ͬ�ij�ʽ�롣���ң�����޸��˳�ʽ���е�ij����ʽ����Ҫ��������ʹ�ô˳�ʽ�����г�ʽ��Ȼ�����������Щ������ʽ�ŵ���ΪACCOUNT.DLL�Ķ�̬�����ʽ���У��Ϳɽ�����������⡣ֻ�ж�̬�����ʽ��ģ��Ű������г�ʽ��Ҫ�õ��ij�ʽ��������Ϊ���浵����ʡ�ŵ��ռ䣬������ͬʱִ�ж��Ӧ�ó�ʽʱ��ʡ�����壬���ң������޸Ķ�̬�����ʽ��ģ��������������������ʽ��

��̬�����ʽ��ʵ�����ǿ��Զ������ڵġ����磬��������д��һϵ��3D��ͼ��ʽ���������Ƿ�����ΪGDI3.DLL��DLL�С�����������巢չ�߶Դ˳�ʽ��ܸ���Ȥ�����Ϳ�����Ȩ���ǽ���������ǵ�ͼ�γ�ʽ�С�ʹ�ö��������ͼ�γ�ʽ��ʹ����ֻ��Ҫһ��GDI3.DLL������

��ʽ�⣺һ�ʶ���
��

��̬�����ʽ���������������ӡ�󣬲���ԭ������춡���ʽ�⡹����ʱ����ڼ��ֲ�ͬ������֮�ᡣ���˶�̬�����ʽ��֮�⣬����Ҳ�������ƺ���Ŀ�����ʽ�⡹�����ó�ʽ�⡹��

Ŀ�����ʽ���Ǵ�.LIB�������ĵ�������ʹ�������ʽ���о�̬����ʱ�����ij�ʽ��ͻ�ӵ���ʽ��.EXE�����С����磬��Microsoft Visual C++�У���ͬ��ʽ�����һ��Cִ��Ŀ�����ʽ�ⱻ��ΪLIBC.LIB��

���ó�ʽ����Ŀ�����ʽ�⵵����һ��������ʽ����Ŀ�����ʽ��һ�������ó�ʽ����.LIB�����������ұ�����������ȷ����ʽ���еĺ�ʽ������Դ�������ó�ʽ�ⲻ����ʽ�룬����Ϊ�����ʽ�ṩ��Ѷ���Ա���.EXE�����н�����̬����ʱҪ�õ����ض�λ����������Microsoft�������е�KERNEL32.LIB��USER32.LIB��GDI32.LIB������Windows��ʽ�����ó�ʽ�⡣���һ����ʽ����Rectangle��ʽ��Rectangle������LINK���ú�ʽ��GDI32.DLL��̬�����ʽ���С�����Ѷ����¼��.EXE�����У�ʹ�ó�ʽִ��ʱ��Windows�ܹ���GDI32.DLL��̬�����ʽ����ж�̬���ᡣ

Ŀ�����ʽ������ó�ʽ��ֻ���ڳ�ʽ�����ڼ�ʹ�ã�����̬�����ʽ����ִ���ڼ�ʹ�á���һ��ʹ�ö�̬�����ʽ��ij�ʽִ��ʱ���ö�̬�����ʽ������ڴ�Ƭ�ϡ���WindowsҪִ��һ��ʹ���˶�̬�����ʽ��ij�ʽ����Ҫ����ó�ʽ��ʱ����̬�����ʽ�⵵�����봢���ں��и�.EXE��ʽ��Ŀ¼�¡�Ŀǰ��Ŀ¼�¡�WindowsϵͳĿ¼�¡�WindowsĿ¼�£���������ͨ��MS-DOS�����е�PATH���Դ�ȡ����Ŀ¼�£�Windows�ᰴ˳��������ЩĿ¼����

һ���򵥵�DLL
��

��Ȼ��̬�����ʽ���������������ǿ��Ա����Ӧ�ó�ʽ��ʹ�ã�����ͨ�������ƵĶ�̬�����ʽ��ֻ��һ��Ӧ�ó�ʽ����ϵ��������һ�������ԡ���ʽ��ʹ��DLL��

�����������Ҫ���ġ����ǽ���һ����ΪEDRLIB.DLL��DLL���������еġ�EDR�����������Ļ�ͼ��ʽ��easy drawing routines�����������EDRLIBֻ����һ����ʽ������ΪEdrCenterText���������������Խ�Ӧ�ó�ʽ�������򵥵Ļ�ͼ��ʽ���ӽ�ȥ��Ӧ�ó�ʽEDRTEST.EXE��ͨ������EDRLIB.DLL�еĺ�ʽ����������

Ҫ������һ�㣬��Ҫ��������ǰ���������в�ͬ�ķ�����Ҳ����Visual C++ ������û�п��������ԡ���Visual C++ �С������ռ䣨workspaces�����͡�ר����projects������ͬ��ר��ͨ���뽨����Ӧ�ó�ʽ��.EXE�����߶�̬�����ʽ�⣨.DLL������ϵ��һ�������ռ���԰���һ������ר��������Ϊֹ���������еĹ����ռ䶼ֻ����һ��ר�����������ھͽ���һ����������ר���Ĺ����ռ�EDRTEST��һ����춽���EDRTEST.EXE������һ����춽���EDRLIB.DLL����EDRTESTʹ�õĶ�̬�����ʽ�⡣

���ھͿ�ʼ����Visual C++�У��ӡ�File�����ܱ�ѡ��New����Ȼ��ѡ��Workspaces��ҳ���ǩ����������ǰ����û��ѡ��������ڡ�Location����ѡ�����ռ�Ҫ�����Ŀ¼��Ȼ���ڡ�Workspace Name�������롸EDRTEST������Enter����

�����ͽ�����һ���յĹ����ռ䡣Developer Studio��������һ����ΪEDRTEST����Ŀ¼���Լ������ռ䵵��EDRTEST.DSW����������������������

�����������ڴ˹����ռ��ィ��һ��ר�����ӡ�File�����ܱ�ѡ��New����Ȼ��ѡ��Projects��ҳ���ǩ�����ܹ�ȥ��ѡ��Win32 Application���������ڡ�Win32 Dynamic-Link Library�������⣬������ѡ��ť��Add To Current Workspace������ʹ�ô�ר���ǡ�EDRTEST�� �����ռ��һ���֡��ڡ�Project Name������EDRLIB�����Ȳ�Ҫ����OK����ť��������Project Name������EDRLIBʱ��Visual C++���ı䡸Location����������ʾEDRLIB��ΪEDRTEST��һ����Ŀ¼���ⲻ������Ҫ�ģ����Խ����ڡ�Location����ɾ��EDRLIB��Ŀ¼�Ա�ר��������EDRTESTĿ¼�����ڰ���OK����өĻ����ʾһ���Ի����飬ѯ��������ʲô��̬��DLL��ѡ��An Empty DLL Project����Ȼ�ᰴ��Finish����Visual C++������һ��ר������EDRLIB.DSP��һ�����쵵��EDRLIB.MAK�������Tools Options���Ի������B��uildҳ���ǩ��ѡ���ˡ�Export Makefile��ѡ���

�������Ѿ��ڴ�ר����������һ�Ե������ӡ�File�����ܱ�ѡ��New����Ȼ��ѡ��Files��ҳ���ǩ��ѡ��C/C++ Header File����Ȼ�����뵵����EDRLIB.H�������ʽ21-1��ʾ�ĵ��������ߴӱ������и��ƣ����ٴδӡ�File�����ܱ���ѡ��New����Ȼ��ѡ��Files��ҳ���ǩ�����ѡ��C++ Source File����Ȼ�����뵵����EDRLIB.C�����������ʽ21-1��ʾ�ij�ʽ��

 ï¿½ï¿½Ê½21-1  EDRLIB��̬�����ʽ��
EDRLIB.H
/*--------------------------------------------------------------------------
   	EDRLIB.H header file
----------------------------------------------------------------------------*/

#ifdef 	__cplusplus
#define 	EXPORT extern "C" __declspec (dllexport)
#else
#define 	EXPORT __declspec (dllexport)
#endif

EXPORT 	BOOL CALLBACK EdrCenterTextA (HDC, PRECT, PCSTR) ;
EXPORT 	BOOL CALLBACK EdrCenterTextW (HDC, PRECT, PCWSTR) ;

#ifdef 	UNICODE
#define 	EdrCenterText EdrCenterTextW
#else
#define 	EdrCenterText EdrCenterTextA
#endif
EDRLIB.C
/*---------------------------------------------------------------------------
   	EDRLIB.C -- Easy Drawing Routine Library module
               						(c) Charles Petzold, 1998
-----------------------------------------------------------------------------*/
#include  windows.h>
#include "edrlib.h"

int WINAPI DllMain (	HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
{
     	return TRUE ;
}

EXPORT BOOL CALLBACK EdrCenterTextA (	HDC hdc, PRECT prc, PCSTR pString)
{
     	int  iLength ;
     	SIZE size ;

     	iLength = lstrlenA (pString) ;
     	GetTextExtentPoint32A (hdc, pString, iLength, &size) ;
     	return TextOutA (hdc,(	prc->right - prc->left - size.cx) / 2,
                           	 (	prc->bottom - prc->top - size.cy) / 2,
                      			pString, iLength) ;
}

EXPORT BOOL CALLBACK EdrCenterTextW (HDC hdc, PRECT prc, PCWSTR pString)
{
     	int  iLength ;
     	SIZE size ;

     	iLength = lstrlenW (pString) ;
     	GetTextExtentPoint32W (hdc, pString, iLength, &size) ;
     	return TextOutW (hdc, 	(	prc->right - prc->left - size.cx) / 2,
                           		(	prc->bottom - prc->top - size.cy) / 2,
                      				pString, iLength) ;
}

���������԰�Release�趨������Ҳ���԰�Debug�趨������EDRLIB.DLL��֮�ᣬRELEASE��DEBUGĿ¼������EDRLIB.LIB������̬�����ʽ������ó�ʽ�⣩��EDRLIB.DLL����̬�����ʽ�Ȿ������

�ݹ�ȫ�飬���ǽ��������г�ʽ�����Ը���UNICODEʶ�����������ʹ��Unicode���Unicode�ִ��ij�ʽ�롣��������һ��DLLʱ����Ӧ�ð���������Ԫ���ִ���Unicode�ͷ�Unicode������к�ʽ����ˣ�EDRLIB.C�Ͱ�����ʽEdrCenterTextA��ANSI�棩��EdrCenterTextW������Ԫ�棩��EdrCenterTextA����Ϊ���в���PCSTR��ָ��const�ִ���ָ�꣩����EdrCenterTextW����Ϊ���в���PCWSTR��ָ��const���ִ���ָ�꣩��EdrCenterTextA��ʽ������lstrlenA��GetTextExtentPoint32A��TextOutA��EdrCenterTextW������lstrlenW��GetTextExtentPoint32W��TextOutW�����������UNICODEʶ���֣���EDRLIB.H��EdrCenterText����ΪEdrCenterTextW��������ΪEdrCenterTextA����������������Windows��ͷ������

EDRLIB.HҲ������ʽDllMain��ȡ����DLL�е�WinMain���˺�ʽ���ִ�г�ʼ����δ��ʼ����deinitialization�����ҽ�����һ�����ۡ�������������Ҫ�ľ��Ǵ�DllMain����TRUE��

�������������У�����һ������֮�����Ƕ�����EXPORTʶ���֡�DLL��Ӧ�ó�ʽʹ�õĺ�ʽ�����ǡ������exported�����ġ����˰�������ҵ�ƶ��޹أ�ֻ��ȷ����ʽ�����ӵ�EDRLIB.LIB��һ���ؼ��֣��Ա������ʽ������ʹ�ô˺�ʽ��Ӧ�ó�ʽʱ���ܹ���������ʽ���ƣ������Ҹú�ʽ��EDRLIB.DLL��Ҳ�ǿ��õ��ġ�EXPORTʶ���ְ������淽ʽ�޶���__declspec��dllexport���Լ��ڱ�ͷ������C++ģʽ����ʱ���ӵġ�C�����⽫��ֹ������ʹ��C++��������ѹ����name mangling����������ʽ���ƣ�ʹC��C++��ʽ����ʹ�����DLL��

��ʽ����ڣ����ڵ�
��

����̬�����ʽ���״������ͽ���ʱ�����Ǻ�����DllMain��ʽ��DllMain�ĵ�һ�������dz�ʽ���ִ��ʵ����š�������ij�ʽ��ʹ����Ҫִ��ʵ����ţ�����DialogBox������Դ����ô��Ӧ�ý�hInstance����Ϊһ�����������DllMain������һ��������ϵͳ������

fdwReason�����������ĸ�ֵ֮һ��˵��ΪʲôWindowsҪ����DllMain��ʽ��������������У����סһ����ʽ���Ա������Σ�����Windows��һ��ִ�С�ÿ��һ����ʽ����ʱ����������Ϊ��һ�������ij���process����

fdwReason��һ��ֵDLL_PROCESS_ATTACH��ʾ��̬�����ʽ�ⱻӳ�䵽һ�������λַ�ռ䡣��ʽ����Ը�������������г�ʼ����Ϊ�������Ըó���������ṩ�������磬�����ʼ�����ܰ������������á���һ����������������ڣ�ֻ��һ�ζ�DllMain�ĺ�����DLL_PROCESS_ATTACHΪ������ʹ��ͬһDLL�������κγ��򶼽�������һ��ʹ��DLL_PROCESS_ATTACH������DllMain���У������Ƕ��³���ĺ��С�

�����ʼ���ɹ���DllMainӦ�ô���һ����0ֵ������0������Windows��ִ�иó�ʽ��

��fdwReason��ֵΪDLL_PROCESS_DETACHʱ����ζ����������ҪDLL�ˣ��Ӷ��ṩ����ʽ���Լ�����Լ��Ļ��ᡣ��32λԪ��Windows�£����ִ����������ϸ����ģ�������һ�����õij�ʽд��ϰ�ߡ�

���Ƶأ�����DLL_THREAD_ATTACHΪfdwReason��������DllMainʱ����ζ��ij����������һ���µ�ִ��������ִ������ֹʱ��Windows��DLL_THREAD_DETACHΪfdwReason��������DllMain����ע�⣬�����̬�����ʽ������ִ����������֮���һ����������ģ���ô���ܻ�õ�һ��û�����ȶ�Ӧһ��DLL_THREAD_ATTACH���е�DLL_THREAD_DETACH���С�

��ʹ��һ��DLL_THREAD_DETACH��������DllMainʱ��ִ������Ȼ���ڡ���̬�����ʽ��������������������ڼ䷢��ִ����ѶϢ����������Ӧ��ʹ��PostMessage����Ϊִ���������ڴ�ѶϢ��������֮ǰ���Ѿ��˳�ִ���ˡ�

���Գ�ʽ
��

������������EDRTEST�����ռ��ィ���ڶ���ר������ʽ����ΪEDRTEST������ʹ��EDRLIB.DLL����Visual C++������EDRTEST�����ռ�ʱ����ӡ�File�����ܱ�ѡ��New����Ȼ���ڡ�New���Ի�������ѡ��Projects��ҳ���ǩ�����ѡ��Win32 Application������ȷ��ѡ���ˡ�Add To Current Workspace����ť������ר������EDRTEST�����ڡ�Locations����ɾ���ڶ���EDRTEST��Ŀ¼�����¡�OK����Ȼ������һ���Ի�����ѡ��An Empty Project��������Finish����

�ӡ�File�����ܱ��ٴ�ѡ��New����ѡ��Files��ҳ���ǩȻ��ѡ��C++ Source File����ȷ����Add To Project���嵥������ʾ��EDRTEST�������ǡ�EDRLIB�������뵵������EDRTEST.C��Ȼ�������ʽ21-2��ʾ�ij�ʽ���˳�ʽ��EdrCenterText��ʽ����ʾ�����е��ִ����ж��롣

 ï¿½ï¿½Ê½21-2  EDRTEST
EDRTEST.C
/*---------------------------------------------------------------------------
   	EDRTEST.C -- Program using EDRLIB dynamic-link library
                						(c) Charles Petzold, 1998
----------------------------------------------------------------------------*/

#include <windows.h>
#include "edrlib.h"

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    							PSTR szCmdLine, int iCmdShow)
{
     	static TCHAR 	szAppName[] = TEXT ("StrProg") ;
     	HWND         				hwnd ;
     	MSG         		 		msg ;
     	WNDCLASS     			wndclass ;

     	wndclass.style         		= CS_HREDRAW | CS_VREDRAW ;
     	wndclass.lpfnWndProc   		= WndProc ;
     	wndclass.cbClsExtra    		= 0 ;
     	wndclass.cbWndExtra    		= 0 ;
     	wndclass.hInstance     		= hInstance ;
     	wndclass.hIcon         		= LoadIcon (NULL, IDI_APPLICATION) ;
     	wndclass.hCursor       		= LoadCursor (NULL, IDC_ARROW) ;
     	wndclass.hbrBackground 	= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     	wndclass.lpszMenuName  	= NULL ;
     	wndclass.lpszClassName 	= szAppName ;
     
     	if (!RegisterClass (&wndclass))
     	{
          		MessageBox (	NULL, TEXT ("This program requires Windows NT!"),
                      							szAppName, MB_ICONERROR) ;
          		return 0 ;
     }
     
     	hwnd = CreateWindow (szAppName, TEXT ("DLL Demonstration Program"),
                          	WS_OVERLAPPEDWINDOW,
                          	CW_USEDEFAULT, CW_USEDEFAULT,
                          	CW_USEDEFAULT, CW_USEDEFAULT,
                          	NULL, NULL, hInstance, NULL) ;

     	ShowWindow (hwnd, iCmdShow) ;
     	UpdateWindow (hwnd) ;
     
     	while (GetMessage (&msg, NULL, 0, 0))
     	{
          		TranslateMessage (&msg) ;
          		DispatchMessage (&msg) ;
     	}
     	return msg.wParam ;
}	

LRESULT CALLBACK WndProc (	HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     	HDC         		hdc ;
     	PAINTSTRUCT 		ps ;
     	RECT        		rect ;
     
     	switch (message)
     	{
     	case 	WM_PAINT:
          			hdc = BeginPaint (hwnd, &ps) ;
          
          			GetClientRect (hwnd, &rect) ;
          
          			EdrCenterText (	hdc, &rect, 
                    TEXT ("This string was displayed by a DLL")) ;
          
          			EndPaint (hwnd, &ps) ;
          			return 0 ;
          
     	case 	WM_DESTROY:
          			PostQuitMessage (0) ;
          			return 0 ;
     	}
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}

ע�⣬Ϊ�˶���EdrCenterText��ʽ��EDRTEST.C����EDRLIB.H��ͷ�������˺�ʽ����WM_PAINTѶϢ�����ڼ���С�

�ڱ���˳�ʽ֮ǰ��������ϣ�������¼����¡����ȣ��ڡ�Project�����ܱ�ѡ��Select Active Project������ʱ����������EDRLIB���͡�EDRTEST����ѡ��EDRTEST���������±���˹����ռ�ʱ��������Ҫ���±�����dz�ʽ�����⣬�ڡ�Project�����ܱ��У�ѡ��Dependencies�����ڡ�Select Project To Modify���嵥������ѡ��EDRTEST�����ڡ�Dependent On The Following Project(s)���б�ѡ�С�EDRLIB�����˲�������˼�ǣ�EDRTEST��ҪEDRLIB��̬�����ʽ�⡣����ÿ�����±���EDRTESTʱ�������Ҫ�Ļ��������ڱ��������EDRTEST֮ǰ�������±���EDRLIB��

�ӡ�Project�����ܱ�ѡ��Settings����������General����ǩ����������ߵĴ�����ѡ��EDRLIB�����ߡ�EDRTEST��ר��ʱ������趨Ϊ��Win32 Release��������ʾ���ұߴ����еġ�Intermediate Files���͡�Output Files����λ�RELEASEĿ¼������趨Ϊ��Win32 Debug������λ�DEBUGĿ¼��������ǣ��밴���޸ġ�������ȷ��EDRLIB.DLL��EDRTEST.EXE��ͬһ��Ŀ¼�У����ҳ�ʽ��ʹ��DLLʱҲ����������⡣

�ڡ�Project Setting���Ի���������Ȼѡ�С�EDRTEST����������C/C++��ҳ���ǩ��������Ĺ������ڡ�Preprocessor Definitions���У�����UNICODE�����ӵ�Debug�趨��

�������Ϳ����ڡ�Debug����Release���趨�����±���EDRTEST.EXE�ˡ���Ҫʱ��Visual C++�����ȱ��������EDRLIB��RELEASE��DEBUGĿ¼������EDRLIB.LIB�����ó�ʽ�⣩��EDRLIB.DLL����Developer Studio����EDRTESTʱ�����Զ��������ó�ʽ�⡣

�˽�EDRTEST.EXE�����в�����EdrCenterText��ʽ�����Ҫ����ʵ�ϣ�Ҫ֤��ִ����EDRLIB.DLL������EdrCenterText��ʽ�ܼ򵥣�ִ��EDRTEST.EXE��ҪEDRLIB.DLL��

ִ��EDRTEST.EXEʱ��Windows���ⲿ��ʽ��ģ��ִ�й̶��ĺ�ʽ���������ຯʽ����һ��Windows��̬�����ʽ���С���WindowsҲ������ʽ��EDRLIB�����˺�ʽ�����Windows��EDRLIB.DLL�������뵽�����壬Ȼ�����EDRLIB�ij�ʼ����ʽ��EDRTEST����EdrCenterText��ʽ�Ƕ�̬���ᵽEDRLIB�к�ʽ�ġ�

��EDRTEST.Cԭʼ�뵵���а���EDRLIB.H�����WINDOWS.H���ơ�����EDRLIB.LIB������Windows���ó�ʽ�⣨����USER32.LIB�����ơ������ij�ʽִ��ʱ��������EDLIB.DLL�ķ�ʽ������USER32.DLL�ķ�ʽ��ͬ����ϲ�������Ѿ���չ��Windows�Ĺ��ܣ�

�ڼ���֮ǰ���һ�Ҫ�Զ�̬�����ʽ���˵��һЩ��

���ȣ���Ȼ���ǽ�DLL��ΪWindows�����죬����Ҳ������Ӧ�ó�ʽ�����졣DLL����ɵ�ÿ���������Ӧ�ó�ʽ��˵����Ӧ�ó�ʽ������Ҫ��ɵġ����磬Ӧ�ó�ʽӵ��DLL���õ�ȫ�������塢DLL������ȫ���Ӵ��Լ�DLL�򿪵����е��������Ӧ�ó�ʽ����ͬʱʹ��ͬһ��DLL������Windows�£���ЩӦ�ó�ʽ�����໥Ӱ�졣

��������ܹ�����һ����̬�����ʽ������ͬ�ij�ʽ�롣���ǣ�DLLΪÿ����������������϶���ͬ��ÿ������ΪDLL��ʹ�õ�ȫ�������������Լ���λַ�ռ䡣���ǽ������Խڿ��������ü�������Ҫ����Ĺ�����

��DLL�й��ü�����
��

�����˷ܵ��ǣ�Windows�ܹ���ͬʱʹ��ͬһ����̬�����ʽ���Ӧ�ó�ʽ�ֿ�����������ʱȴ��̫�������⡣������ϣ��дһ��DLL�����а����ܹ�����ͬӦ�ó�ʽ����ͬһ����ʽ�IJ�ͬ��ʽ�����õļ����塣�����ʹ�ù��ü����塣���ü�����ʵ������һ�ּ�����ӳ�䵵����

�����Dz���һ�£������������ڳ�ʽSTRPROG�����ִ���ʽ��string program�������Ͷ�̬�����ʽ��STRLIB�����ִ���ʽ�⣨string library����������ɵġ�STRLIB�����������ʽ��STRPROG���У�����ֻ�Դ˸���Ȥ��STRLIB�е�һ����ʽʹ������STRPROG�����callback��ʽ��

STRLIB��һ����̬�����ʽ��ģ�飬�����沢���������256���ִ�����STRLIB�У���Щ�ִ���Ϊ��д�����ɹ��ü�����ά��������STRLIB��������ʽ��STRPROG�ܹ������ִ���ɾ���ִ��Լ���STRLIB���Ŀǰ�������ִ���STRPROG���Գ�ʽ���������ܱ����Enter���͡�Delete���������������ܱ��������ͬ�ĶԻ����������ӻ�ɾ���ִ���STRPROG������ʾ�����г�Ŀǰ������STRLIB�е������ִ���

���������ʽ��STRLIB���壬����һ���ִ����ӵ�STRLIB�Ĺ��ü����塣

EXPORT BOOL CALLBACK AddString (pStringIn)

����pStringIn���ִ���ָ�ꡣ�ִ���AddString��ʽ�б�ɴ�д�������STRLIB���б�����һ����ͬ���ִ�����ô�˺�ʽ������һ���ִ��ĸ���������ɹ���AddString���ء�TRUE������0�������򴫻ء�FALSE����0��������ִ��ij���Ϊ0�����߲������ô����ִ��ļ����壬�����Ѿ�������256���ִ����򴫻�ֵ������FALSE��

STRLIB��ʽ��STRLIB�Ĺ��ü�������ɾ��һ���ִ���

EXPORT BOOL CALLBACK DeleteString (pStringIn)

���⣬����pStringIn��һ���ִ�ָ�ꡣ����ж����ͬ�����ִ�����ɾ����һ��������ɹ�����ôDeleteString���ء�TRUE������0�������򴫻ء�FALSE����0�������ء�FALSE����ʾ�ִ�����Ϊ0�������Ҳ�����ͬ���ݵ��ִ���

STRLIB��ʽʹ���˺��г�ʽ�е�һ��callback��ʽ���Ա��г�Ŀǰ������STRLIB���ü������е��ִ���

EXPORT int CALLBACK GetStrings (pfnGetStrCallBack, pParam)

�ں��г�ʽ�У�callback��ʽ�����������������壺

EXPORT BOOL CALLBACK GetStrCallBack (PSTR pString, PVOID pParam)

GetStrings�IJ���pfnGetStrCallBackָ��callback��ʽ��ֱ��callback��ʽ���ء�FALSE����0����GetStrings��Ϊÿ���ִ�������һ��GetStrCallBack��GetStrings���ش��ݸ�callback��ʽ���ִ�����pParam������һ��Զ��ָ�ָ꣬���ʽд���߶�������ϡ�

��Ȼ���˳�ʽ���Ա����Unicode��ʽ��������STRLIB��֧Ԯ�£������Unicode�ͷ�UnicodeӦ�ó�ʽ����EDRLIBһ�������еĺ�ʽ���С�A���͡�W�����ְ汾�����ڲ���STRLIB��Unicode�������е��ִ��������Unicode��ʽʹ����STRLIB��Ҳ����˵����ʽ������AddStringA��DeleteStringA��GetStringsA�����ִ�����Unicode�ͷ�Unicode֮��ת����

��STRPROG��STRLIBר����صĹ����ռ���ΪSTRPROG���˵�����EDRTEST�����ռ�ķ�ʽ��ϡ���ʽ21-3��ʾ�˽���STRLIB.DLL��̬�����ʽ�������������������

 ï¿½ï¿½Ê½21-3  STRLI
STRLIB.H
/*----------------------------------------------------------------------------
   	STRLIB.H header file
-----------------------------------------------------------------------------*/

#ifdef __cplusplus
#define EXPORT extern "C" __declspec (dllexport)
#else
#define EXPORT __declspec (dllexport)
#endif

     	// The maximum number of strings STRLIB will store and their lengths
#define 	MAX_STRINGS 256
#define 	MAX_LENGTH  63

     	// The callback function type definition uses generic strings

typedef BOOL (CALLBACK * GETSTRCB) (PCTSTR, PVOID) ;

     	// Each function has ANSI and Unicode versions

EXPORT 	BOOL CALLBACK AddStringA (PCSTR) ;
EXPORT 	BOOL CALLBACK AddStringW (PCWSTR) ;

EXPORT 	BOOL CALLBACK DeleteStringA (PCSTR) ;
EXPORT 	BOOL CALLBACK DeleteStringW (PCWSTR) ;

EXPORT 	int CALLBACK GetStringsA (GETSTRCB, PVOID) ;
EXPORT 	int CALLBACK GetStringsW (GETSTRCB, PVOID) ;
 
     	// Use the correct version depending on the UNICODE identifier

#ifdef 	UNICODE
#define 	AddString    	AddStringW
#define 	DeleteString 		DeleteStringW
#define 	GetStrings   		GetStringsW
#else
#define 	AddString    	AddStringA
#define 	DeleteString 		DeleteStringA
#define 	GetStrings   		GetStringsA
#endif
STRLIB.C
/*---------------------------------------------------------------------------
   	STRLIB.C - 	Library module for STRPROG program
               					(c) Charles Petzold, 1998
----------------------------------------------------------------------------*/

#include <windows.h>
#include <wchar.h>       				// for wide-character string functions
#include "strlib.h"

	// shared memory section (requires /SECTION:shared,RWS in link options)
#pragma 		data_seg ("shared")
int   			iTotal = 0 ;
WCHAR 			szStrings [MAX_STRINGS][MAX_LENGTH + 1] = { '\0' } ;
#pragma 		data_seg ()

#pragma 		comment(linker,"/SECTION:shared,RWS")

int WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
{
	return TRUE ;
}

EXPORT BOOL CALLBACK AddStringA (PCSTR pStringIn)
{
     	BOOL  		bReturn ;
     	int   		iLength ;
     	PWSTR 		pWideStr ;

	// Convert string to Unicode and call AddStringW
     	iLength = MultiByteToWideChar (CP_ACP, 0, pStringIn, -1, NULL, 0) ;
     	pWideStr = malloc (iLength) ;
     	MultiByteToWideChar (CP_ACP, 0, pStringIn, -1, pWideStr, iLength) ;
     	bReturn = AddStringW (pWideStr) ;
     	free (pWideStr) ;

     	return bReturn ;
}

EXPORT BOOL CALLBACK AddStringW (PCWSTR pStringIn)
{
     	PWSTR 		pString ;
     	int   		i, iLength ;
     
     	if (iTotal == MAX_STRINGS - 1)
          			return FALSE ;
     	if ((iLength = wcslen (pStringIn)) == 0)
          			return FALSE ;
          		// Allocate memory for storing string, copy it, convert to uppercase
     	pString = malloc (sizeof (WCHAR) * (1 + iLength)) ;
     	wcscpy (pString, pStringIn) ;
     	_wcsupr (pString) ;

          		//  Alphabetize the strings
     	for (i = iTotal ; i > 0 ; i-)
     	{
          		if (wcscmp (pString, szStrings[i - 1]) >= 0)
               				break ;
          		wcscpy (szStrings[i], szStrings[i - 1]) ;
     	}
     	wcscpy (szStrings[i], pString) ;
     	iTotal++ ;

     	free (pString) ;
     	return TRUE ;
}

EXPORT BOOL CALLBACK DeleteStringA (PCSTR pStringIn)
{
     	BOOL  		bReturn ;
     	int   		iLength ;
     	PWSTR 		pWideStr ;

          			// Convert string to Unicode and call DeleteStringW

     	iLength = MultiByteToWideChar (CP_ACP, 0, pStringIn, -1, NULL, 0) ;
     	pWideStr = malloc (iLength) ;
     	MultiByteToWideChar (CP_ACP, 0, pStringIn, -1, pWideStr, iLength) ;
     	bReturn = DeleteStringW (pWideStr) ;
     	free (pWideStr) ;

     	return bReturn ;
}

EXPORT BOOL CALLBACK DeleteStringW (PCWSTR pStringIn)
{
     	int i, j ;
     	if (0 == wcslen (pStringIn))
          			return FALSE ;
     	for (i = 0 ; i < iTotal ; i++)
  	{
          		if (_wcsicmp (szStrings[i], pStringIn) == 0)
               				break ;
   	}
          		// If given string not in list, return without taking action
     	if (i == iTotal)
          			return FALSE ;
          		// Else adjust list downward
     	for (j = i ; j < iTotal ; j++)
          			wcscpy (szStrings[j], szStrings[j + 1]) ;
     	szStrings[iTotal-][0] = '\0' ;
     	return TRUE ;
}

EXPORT int CALLBACK GetStringsA (GETSTRCB pfnGetStrCallBack, PVOID pParam)
{
     	BOOL 		bReturn ;
     	int  		i, iLength ;
     	PSTR 		pAnsiStr ;

	for (i = 0 ; i < iTotal ; i++)
     	{
               			// Convert string from Unicode
iLength = WideCharToMultiByte (	CP_ACP, 0, szStrings[i], -1, NULL, 0, NULL, NULL) ;
			pAnsiStr = malloc (iLength) ;
          WideCharToMultiByte (	CP_ACP, 0, szStrings[i], -1, pAnsiStr, iLength, NULL, NULL) ;

               					// Call callback function

			bReturn = pfnGetStrCallBack (pAnsiStr, pParam) ;
          
			if (bReturn == FALSE)
               					return i + 1 ;

			free (pAnsiStr) ;
     	}
     	return iTotal ;
}

EXPORT int CALLBACK GetStringsW (GETSTRCB pfnGetStrCallBack, PVOID pParam)
{
     	BOOL 		bReturn ;
     	int  		i ;
     
     	for (i = 0 ; i < iTotal ; i++)
     	{
          		bReturn = pfnGetStrCallBack (szStrings[i], pParam) ;
          		if (bReturn == FALSE)
               				return i + 1 ;
     	}
     	return iTotal ;
}

����DllMain��ʽ���⣬STRLIB��ֻ��������ʽ��������ʽ����á�������Щ��ʽ����EXPORT���塣���ʹLINK��STRLIB.LIB���ó�ʽ�����г����ǡ�

STRPROG��ʽ
��

STRPROG��ʽ���ʽ21-4��ʾ���������൱dz���׶����������ܱ�ѡ��(Enter��Delete)����һ���Ի����飬��������һ���ִ���Ȼ��STRPROG����AddString����DeleteString������ʽ��Ҫ����������ʾ����ʱ������GetStrings��ʹ�ú�ʽGetStrCallBack���г����оٵ��ִ���

 ï¿½ï¿½Ê½21-4  STRPROG
STRPROG.C
/*----------------------------------------------------------------------------
   	STRPROG.C -	Program using STRLIB dynamic-link library
                						(c) Charles Petzold, 1998
-----------------------------------------------------------------------------*/

#include <windows.h>
#include "strlib.h"
#include "resource.h"

typedef struct
{
     	HDC 	hdc ;
     	int 	xText ;
     	int 	yText ;
     	int 	xStart ;
     	int 	yStart ;
     	int 	xIncr ;
     	int 	yIncr ;
     	int 	xMax ;
     	int 	yMax ;
}
CBPARAM ;
LRESULT 	CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
TCHAR 		szAppName [] = TEXT ("StrProg") ;
TCHAR szString [MAX_LENGTH + 1] ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    							PSTR szCmdLine, int iCmdShow)
{
     	HWND     			hwnd ;
     	MSG    			msg ;
     	WNDCLASS 		wndclass ;
     
     	wndclass.style         			= CS_HREDRAW | CS_VREDRAW ;
     	wndclass.lpfnWndProc   			= WndProc ;
     	wndclass.cbClsExtra    			= 0 ;
     	wndclass.cbWndExtra    			= 0 ;
     	wndclass.hInstance     			= hInstance ;
     	wndclass.hIcon         			= LoadIcon (NULL, IDI_APPLICATION) ;
     	wndclass.hCursor      	 		= LoadCursor (NULL, IDC_ARROW) ;
     	wndclass.hbrBackground 		= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     	wndclass.lpszMenuName  		= szAppName ;
     	wndclass.lpszClassName 		= szAppName ;
     
     	if (!RegisterClass (&wndclass))
     	{
          		MessageBox (	NULL, TEXT ("This program requires Windows NT!"),
                      							szAppName, MB_ICONERROR) ;
          		return 0 ;
     }

     	hwnd = CreateWindow (	szAppName, TEXT ("DLL Demonstration Program"),
                          		WS_OVERLAPPEDWINDOW,
                          		CW_USEDEFAULT, CW_USEDEFAULT,
                          		CW_USEDEFAULT, CW_USEDEFAULT,
                          		NULL, NULL, hInstance, NULL) ;
     
     	ShowWindow (hwnd, iCmdShow) ;
     	UpdateWindow (hwnd) ;
     
     	while (GetMessage (&msg, NULL, 0, 0))
     	{
          		TranslateMessage (&msg) ;
          		DispatchMessage (&msg) ;
     	}
     	return msg.wParam ;
}

BOOL CALLBACK DlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
     	switch (message)
     	{
     	case 	WM_INITDIALOG:
          			SendDlgItemMessage (hDlg, IDC_STRING, EM_LIMITTEXT, MAX_LENGTH, 0) ;
          			return TRUE ;
          
     	case 	WM_COMMAND:
          			switch (wParam)
          			{
          			case 	IDOK:
               					GetDlgItemText (hDlg, IDC_STRING, szString, MAX_LENGTH) ;
               					EndDialog (hDlg, TRUE) ;
               					return TRUE ;
               
          			case 	IDCANCEL:
               					EndDialog (hDlg, FALSE) ;
               					return TRUE ;
         	 		}
     	}
     	return FALSE ;
}

BOOL CALLBACK GetStrCallBack (PTSTR pString, CBPARAM * pcbp)
{
     	TextOut (	pcbp->hdc, pcbp->xText, pcbp->yText,
              					pString, lstrlen (pString)) ;
     
     	if ((pcbp->yText += pcbp->yIncr) > pcbp->yMax)
     	{
          			pcbp->yText = pcbp->yStart ;
          			if ((pcbp->xText += pcbp->xIncr) > pcbp->xMax)
               					return FALSE ;
     	}
     	return TRUE ;
}

LRESULT CALLBACK WndProc (	HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     	static HINSTANCE  		hInst ;
     	static int        				cxChar, cyChar, cxClient, cyClient ;
     	static UINT       			iDataChangeMsg ;
     	CBPARAM           					cbparam ;
     	HDC               						hdc ;
     	PAINTSTRUCT       				ps ;
     	TEXTMETRIC        				tm ;
     
     	switch (message)
     	{
     	case 	WM_CREATE:
          			hInst 		= ((LPCREATESTRUCT) lParam)->hInstance ;
          			hdc   = GetDC (hwnd) ;
          			GetTextMetrics (hdc, &tm) ;
          			cxChar 	= (int) tm.tmAveCharWidth ;
          			cyChar 	= (int) (tm.tmHeight + tm.tmExternalLeading) ;
          			ReleaseDC (hwnd, hdc) ;

               				// Register message for notifying instances of data changes

	iDataChangeMsg = RegisterWindowMessage (TEXT ("StrProgDataChange")) ;
			return 0 ;
     	case 	WM_COMMAND:
          			switch (wParam)
          			{
          			case 	IDM_ENTER:
               					if (DialogBox (hInst, TEXT ("EnterDlg"), hwnd, &DlgProc))
               					{
                   if (AddString (szString))
                    PostMessage (HWND_BROADCAST, iDataChangeMsg, 0, 0) ;
                   else
                        MessageBeep (0) ;
               		}
               	break ;
               
          			case 	IDM_DELETE:
					if (DialogBox (hInst, TEXT ("DeleteDlg"), hwnd, &DlgProc))
               					{
                    if (DeleteString (szString))
                    PostMessage (HWND_BROADCAST, iDataChangeMsg, 0, 0) ;
                   else
                   MessageBeep (0) ;
               					}
        					break ;
          			}
          			return 0 ;
          
     	case 	WM_SIZE:
          			cxClient = (int) LOWORD (lParam) ;
          			cyClient = (int) HIWORD (lParam) ;
          			return 0 ;

     	case 	WM_PAINT:
          			hdc = BeginPaint (hwnd, &ps) ;
               
          			cbparam.hdc 		= hdc ;
          			cbparam.xText	= cbparam.xStart = cxChar ;
          			cbparam.yText	= cbparam.yStart = cyChar ;
          			cbparam.xIncr	= cxChar * MAX_LENGTH ;
          			cbparam.yIncr	= cyChar ;
          			cbparam.xMax 	= cbparam.xIncr * (1 + cxClient / cbparam.xIncr) ;
          			cbparam.yMax	= cyChar * (cyClient / cyChar - 1) ;
               
          			GetStrings ((GETSTRCB) GetStrCallBack, (PVOID) &cbparam) ;
              
          			EndPaint (hwnd, &ps) ;
          			return 0 ;
               
     	case 	WM_DESTROY:
          			PostQuitMessage (0) ;
          			return 0 ;

     	default:
          		if (message == iDataChangeMsg)
               				InvalidateRect (hwnd, NULL, TRUE) ;
          		break ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}
 STRPROG.RC ��ժ¼��
//Microsoft Developer Studio generated resource script.
#include "resource.h"
#include "afxres.h"

/////////////////////////////////////////////////////////////////////////////
// Dialog
ENTERDLG DIALOG DISCARDABLE  20, 20, 186, 47
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Enter"
FONT 8, "MS Sans Serif"
BEGIN
    	LTEXT           					"&Enter:",IDC_STATIC,7,7,26,9
    	EDITTEXT        				IDC_STRING,31,7,148,12,ES_AUTOHSCROLL
    	DEFPUSHBUTTON   		"OK",IDOK,32,26,50,14
    	PUSHBUTTON      			"Cancel",IDCANCEL,104,26,50,14
END
DELETEDLG DIALOG DISCARDABLE  20, 20, 186, 47
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Delete"
FONT 8, "MS Sans Serif"
BEGIN
    	LTEXT           					"&Delete:",IDC_STATIC,7,7,26,9
    	EDITTEXT        				IDC_STRING,31,7,148,12,ES_AUTOHSCROLL
    	DEFPUSHBUTTON   		"OK",IDOK,32,26,50,14
    	PUSHBUTTON      			"Cancel",IDCANCEL,104,26,50,14
END

/////////////////////////////////////////////////////////////////////////////
// Menu
STRPROG MENU DISCARDABLE 
BEGIN
	MENUITEM "&Enter!", 	                    				IDM_ENTER
    	MENUITEM "&Delete!",                    					IDM_DELETE
END
 RESOURCE.H ��ժ¼��
// Microsoft Developer Studio generated	include file.
// Used by StrProg.rc

#define 		IDC_STRING                      					1000
#define 		IDM_ENTER                       					40001
#define 		IDM_DELETE                      					40002
#define 		IDC_STATIC                      					-1

STRPROG.C����STRLIB.H��ͷ���������ж�����STRPROG��ʹ�õ�STRLIB�е�������ʽ��

����ִ��STRPROG�Ķ��ִ��ʵ���ʱ�򣬱���ʽ�İ���֮���ͻ���¶������STRLIB���ڹ��ü������д����ִ�����ָ�꣬������STRPROG�е�����ִ��ʵ�干�ô����ϡ������ǿ�һ���������ִ�еİɡ�

��STRPROGִ��ʵ��֮�乲������
��

Windows��һ��Win32�����λַ�ռ���Χ����һ��ǽ��ͨ����һ�������λַ�ռ��е�������˽�еģ��Ա�ij�������Dz��ɼ��ġ�����ִ��STRPROG�Ķ��ִ��ʵ���ʾ��STRLIB�ڳ�ʽ������ִ��ʵ��֮�乲�������Ǻ�������ġ�������һ��STRPROG�Ӵ������ӻ���ɾ��һ���ִ�ʱ�����ָı佫������ӳ���������Ӵ��С�

��ȫ����ʽ֮�䣬STRLIB��������������һ����Ԫ���к�һ����������¼�Ѵ������Ч�ִ��ĸ�������STRLIB�����������������ڹ��õ�һ����������������У�

#pragma 	data_seg ("shared")
int   		iTotal = 0 ;
WCHAR 		szStrings [MAX_STRINGS][MAX_LENGTH + 1] = { '\0' } ;
#pragma 	data_seg ()

��һ��#pragma�����������϶Σ���������Ϊshared�������Խ��������Ϊ�κ�һ����ϲ�������֡��������#pragma����֮������г�ʼ���˵ı���������shared���϶��С��ڶ���#pragma������ʾ�εĽ������Ա�������ר�ŵij�ʼ���Ǻ���Ҫ�ģ�����������������Ƿ�����ͨ��δ��ʼ�����϶��ж����Ƿ���shared�С�

����������֪����һ����shared���������϶Ρ��ڡ�Project Settings���Ի�����ѡ��Link��ҳ���ǩ��ѡ�С�STRLIB��ʱ�ڡ�Project Options����λ����Release��Debug�趨�о��ɣ����������������������

/SECTION:shared,RWS

��ĸRWS��ʾ�ξ��ж���д�͹������ԡ����ߣ���Ҳ����ֱ����DLLԭʼ��ָ������ѡ�����������STRLIB.C������

#pragma comment(linker,"/SECTION:shared,RWS")

���õļ����������iTotal������szStrings�ִ�������STRLIB�����г�ʽ֮�乲�á���ΪMAX_STRINGS���256����MAX_LENGTH���63�����ԣ����ü�����εij���Ϊ32,772λԪ�飭iTotal������Ҫ4λԪ�飬256��ָ���е�ÿһ������Ҫ128λԪ�顣

ʹ�ù��ü�����ο������ڶ��Ӧ�ó�ʽ�乲�����ϵ���򵥵ķ����������Ҫ��̬���ù��ü�����ռ䣬��Ӧ�ò鿴������ӳ�䵵��������÷����ļ���/Platform SDK/Windows Base Services/Interprocess Communication/File Mapping��

��ʽ������DLL����
��

��ǰ��������̬�����ʽ��ģ�鲻����ѶϢ�����ǣ���̬�����ʽ��ģ��ɺ���GetMessage��PeekMessage��ʵ���ϣ���ѶϢ�����еõ���ѶϢ�Ƿ������г�ʽ�⺯ʽ�ij�ʽ�ġ�һ����˵����ʽ������������ij�ʽ�����ģ�����һ��Գ�ʽ�������еĴ����Windows��ʽ�����õĹ���

��̬�����ʽ����Դӳ�ʽ�⵵�����ߴӺ��г�ʽ��ij�ʽ������������Դ����ͼʾ���ִ��͵���ͼ����������Դ�ĺ�ʽ��Ҫִ��ʵ����š������ʽ��ʹ�����Լ���ִ��ʵ����ţ���ʼ���ڼ䴫����ʽ��ģ������ʽ���ܴ����Լ��ĵ����л����Դ��Ϊ�˴Ӻ��г�ʽ��.EXE�����еõ���Դ����ʽ��ʽ�⺯ʽ��Ҫ���иú�ʽ�ij�ʽ��ִ��ʵ����š�

�ڳ�ʽ���е�¼�Ӵ����ͽ����Ӵ���Ҫһ�㼼�ɡ��Ӵ����ṹ��CreateWindow���ж���Ҫִ��ʵ����š������ڽ����Ӵ������Ӵ�ʱ��ʹ�ö�̬�����ʽ��ģ���ִ��ʵ����ţ����ڳ�ʽ�⽨���Ӵ�ʱ���Ӵ�ѶϢ�Իᷢ�͵����г�ʽ���г�ʽ��ѶϢ���С����ʹ���߱����ڳ�ʽ���н����Ӵ������Ӵ�����õķ���������ʹ�ú��г�ʽ��ִ��ʵ����š�

��Ϊģ̬�Ի������ѶϢ���ڳ�ʽ��ѶϢ��Ȧ֮����յ��ģ����ʹ���߿����ڳ�ʽ���к���DialogBox������ģ̬�Ի����顣ִ��ʵ����ſ����dz�ʽ����ţ�����DialogBox��hwndParent��������ΪNULL��

��������������Ѷ�Ķ�̬����
��

�����ڵ�һ�ΰ�ʹ���߳�ʽ���������ʱ����Windowsִ�ж�̬�����⣬��ʽִ��ʱҲ���԰ѳ�ʽͬ��̬�����ʽ��ģ�����ᵽһ�����磬��ͨ������������Rectangle��ʽ��

Rectangle (hdc, xLeft, yTop, xRight, yBottom) ;

��Ϊ��ʽ��GDI32.LIB���ó�ʽ�����ᣬ�ó�ʽ���ṩ��Rectangle��λַ��������ַ�����Ч��

��Ҳ�����ø��ػصķ�������Rectangle��������typedefΪRectangle����һ����ʽ��̬��

typedef BOOL (WINAPI * PFNRECT) (HDC, int, int, int, int) ;

Ȼ�ᶨ������������

HANDLE	hLibrary ;
PFNRECT	pfnRectangle ;

���ڽ�hLibrary�趨Ϊ��ʽ����ţ���lpfnRectangle�趨ΪRectangle��ʽ��λַ��

hLibrary = LoadLibrary (TEXT ("GDI32.DLL"))
pfnRectangle = (PFNPRECT) GetProcAddress (hLibrary, TEXT ("Rectangle"))

����Ҳ�����ʽ�⵵�����߷�������һЩ����LoadLibrary��ʽ����NULL�����������Ժ��к�ʽȻ���ͷų�ʽ�⣺

pfnRectangle (hdc, xLeft, yTop, xRight, yBottom) ;
FreeLibrary (hLibrary) ;

��������ִ��ʱ�ڶ�̬����ļ�����û��ΪRectangle��ʽ���Ӷ��ô��������϶������õģ����ֱ��ִ��ʱ����֪����ʽ��̬�����ʽ��ģ������ƣ���ʱ����Ҫʹ������

����ij�ʽ��ʹ����LoadLibrary��FreeLibrary��ʽ��WindowsΪ���еĶ�̬�����ʽ��ģ���ṩ�����ü�������LoadLibraryʹ���ü�����������Windows�����κ�ʹ���˳�ʽ��ij�ʽʱ�����ü���Ҳ�������FreeLibraryʹ���ü����ݼ�����ʹ���˳�ʽ��ij�ʽִ��ʵ�����ʱҲ����ˡ������ü���Ϊ��ʱ��Windows���Ӽ������аѳ�ʽ��ɾ��������Ϊ������Ҫ���ˡ�

����Դ��ʽ��
��

����Windows��ʽ��������ʽ��ʹ�õĶ�̬�����ʽ���е��κκ�ʽ�����뱻�����Ȼ����DLLҲ���Բ������κ������ʽ����ô��DLL���װ���ʲô�أ�������Դ��

����ʹ��������ʹ����Ҫ��������ͼ��WindowsӦ�ó�ʽ���й�����ͨ��Ҫ�ڳ�ʽ����Դ���������г���Դ������LoadBitmap��ʽ��������������塣��ʹ���߿���ϣ�����������׵���ͼ��ÿһ�׾������Windows��ʹ�õIJ�ͬ��ʾ��������ͬ�׵ĵ���ͼ��ŵ���ͬ�����п��������ǵģ���Ϊֻ��Ҫ��Ӳ���ϱ���һ�׵���ͼ����Щ�������Ǵ���Դ������

��ʽ21-5˵����ν�������9������ͼ����ΪBITLIB.DLL�Ĵ���Դ��ʽ�⵵����BITLIB.RC�����г������ж����ĵ���ͼ������Ϊÿ����������һ����š�Ϊ�˽���BITLIB.DLL����Ҫ9����ΪBITMAP1.BMP��BITMAP2.BMP�ȵȵĵ���ͼ��������ʹ�ø����Ĺ�����ṩ�ĵ���ͼ������Visual C++�н�����Щ����ͼ��������ID��1��9���Ӧ��

 ï¿½ï¿½Ê½21-5  BITLIB
BITLIB.C
/*--------------------------------------------------------------
   	BITLIB.C --	Code entry point for BITLIB dynamic-link library
               						(c) Charles Petzold,  1998
------------------------------------------------------------------*/

#include <windows.h>
int WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
{
     	return TRUE ;
}
 BITLIB.RC ��ժ¼��
//Microsoft Developer Studio generated resource script.
#include "resource.h"
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
// Bitmap
1                 BITMAP  DISCARDABLE     "bitmap1.bmp"
2                 BITMAP  DISCARDABLE     "bitmap2.bmp"
3                 BITMAP  DISCARDABLE     "bitmap3.bmp"
4                 BITMAP  DISCARDABLE     "bitmap4.bmp"
5                 BITMAP  DISCARDABLE     "bitmap5.bmp"
6                 BITMAP  DISCARDABLE     "bitmap6.bmp"
7                 BITMAP  DISCARDABLE     "bitmap7.bmp"
8                 BITMAP  DISCARDABLE     "bitmap8.bmp"
9                 BITMAP  DISCARDABLE     "bitmap9.bmp"

����ΪSHOWBIT�Ĺ����ռ��н���BITLIBר��������ΪSHOWBIT����һ��ר���У�������ʽ21-6��ʾ��SHOWBIT��ʽ������ǰ���һ������������ҪʹBITLIB�����SHOWBIT��������������н���ҪBITLIB.LIB������������ΪBITLIBû���κ������ʽ����Ҳ���Ὠ��BITLIB.LIB����ʵ�ϣ�Ҫ�ֱ����±���BITLIB��SHOWBIT�����Խ����趨����һ��Ϊ��Active Project��Ȼ�������±��롣

SHOWBIT.C��BITLIB��ȡ����ͼ��Դ��Ȼ��������ʾ������ʾ���������ϵ����������ѭ����ʾ��

 ï¿½ï¿½Ê½21-6  SHOWBIT
SHOWBIT.C
/*--------------------------------------------------------------------------
   	SHOWBIT.C -- Shows bitmaps in BITLIB dynamic-link library
                						(c) Charles Petzold, 1998
---------------------------------------------------------------------------*/

#include <windows.h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

TCHAR szAppName [] = TEXT ("ShowBit") ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    							PSTR szCmdLine, int iCmdShow)
{
     	HWND     			hwnd ;
     	MSG      			msg ;
     	WNDCLASS 		wndclass ;

     	wndclass.style         			= CS_HREDRAW | CS_VREDRAW ;
     	wndclass.lpfnWndProc   			= WndProc ;
     	wndclass.cbClsExtra    			= 0 ;
     	wndclass.cbWndExtra    			= 0 ;
     	wndclass.hInstance    			    = hInstance ;
     	wndclass.hIcon         			= LoadIcon (NULL, IDI_APPLICATION) ;
     	wndclass.hCursor       			= LoadCursor (NULL, IDC_ARROW) ;
     	wndclass.hbrBackground 		= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     	wndclass.lpszMenuName  = NULL ;
     	wndclass.lpszClassName 		= szAppName ;
     
     	if (!RegisterClass (&wndclass))
     {
     		MessageBox (	NULL, TEXT ("This program requires Windows NT!"),
                      							szAppName, MB_ICONERROR) ;
          		return 0 ;
     }

     hwnd = CreateWindow (szAppName, 
            TEXT ("Show Bitmaps from BITLIB (Press Key)"),
                 WS_OVERLAPPEDWINDOW,
                 CW_USEDEFAULT, CW_USEDEFAULT,
                 CW_USEDEFAULT, CW_USEDEFAULT,
                 NULL, NULL, hInstance, NULL) ;

	if (!hwnd)
          			return 0 ;
     	ShowWindow (hwnd, iCmdShow) ;
     	UpdateWindow (hwnd) ;
     
 	while (GetMessage (&msg, NULL, 0, 0))
     	{
          TranslateMessage (&msg) ;
          DispatchMessage (&msg) ;
     	} 
     	return msg.wParam ;
}

void DrawBitmap (HDC hdc, int xStart, int yStart, HBITMAP hBitmap)
{	
     	BITMAP 		bm ;
     	HDC   			hMemDC ;
     	POINT  			pt ;

     	hMemDC = CreateCompatibleDC (hdc) ;
     	SelectObject (hMemDC, hBitmap) ;
     	GetObject (hBitmap, sizeof (BITMAP), &bm) ;
     	pt.x = bm.bmWidth ;
     	pt.y = bm.bmHeight ;
     
	BitBlt (hdc, xStart, yStart, pt.x, pt.y, hMemDC, 0, 0, SRCCOPY) ;
     	DeleteDC (hMemDC) ;
}

LRESULT CALLBACK WndProc (	HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     	static HINSTANCE 		hLibrary ;
     	static int       				iCurrent = 1 ;
     	HBITMAP          					hBitmap ;
     	HDC              						hdc ;
     	PAINTSTRUCT      				ps ;

     	switch (message)
     	{	
     	case 	WM_CREATE:
          			if ((hLibrary = LoadLibrary (TEXT ("BITLIB.DLL"))) == NULL)
          			{
           MessageBox (	hwnd, TEXT ("Can't load BITLIB.DLL."),
                        szAppName, 0) ;
           return -1 ;
       			}
          		return 0 ;
          
     	case 	WM_CHAR:
          			if (hLibrary)
          			{
               				iCurrent ++ ;
               				InvalidateRect (hwnd, NULL, TRUE) ;
          			}
          			return 0 ;
     	case 	WM_PAINT:
          			hdc = BeginPaint (hwnd, &ps) ;
          
          			if (hLibrary)
          			{
               		hBitmap = LoadBitmap (hLibrary, MAKEINTRESOURCE (iCurrent)) ;

               				if (!hBitmap) 
               				{
                    					iCurrent = 1 ;
                    					hBitmap = LoadBitmap (	hLibrary, 
                                        MAKEINTRESOURCE (iCurrent)) ;
               				}
               				if (hBitmap)
               					{
                    						DrawBitmap (hdc, 0, 0, hBitmap) ;
                    					DeleteObject (hBitmap) ;
               }
          			}
          			EndPaint (hwnd, &ps) ;
          			return 0 ;
          
     	case 	WM_DESTROY:
          			if (hLibrary)
               					FreeLibrary (hLibrary) ;

          			PostQuitMessage (0) ;
          			return 0 ;
     	}
     	return DefWindowProc (hwnd, message, wParam, lParam) ;
}

�ڴ���WM_CREATEѶϢ�����ڼ䣬SHOWBIT�����BITLIB.DLL�Ĵ��ţ�

if ((hLibrary = LoadLibrary (TEXT ("BITLIB.DLL"))) == NULL)

���BITLIB.DLL��SHOWBIT.EXE����ͬһ��Ŀ¼��Windows��������ǰ�����۵ķ������������LoadLibrary����NULL��SHOWBIT��ʾһ��ѶϢ������������󣬲���WM_CREATEѶϢ����-1���⽫����WinMain�е�CreateWindow���д���NULL�����ҳ�ʽ��ֹ��ʽ��

SHOWBIT͸����ʽ����ź͵���ͼ����������LoadBitmap���Ӷ��õ�һ������ͼ���ţ�

hBitmap = LoadBitmap (hLibrary, MAKEINTRESOURCE (iCurrent)) ;

�������iCurrent��Ӧ�ĵ���ͼ��Ч����û���㹻�ļ������������ͼ���򴫻�һ������

�ڴ���WM_DESTROYѶϢʱ��SHOWBIT�ͷų�ʽ�⣺

FreeLibrary (hLibrary) ;

��SHOWBIT������һ��ִ��ʵ����ֹʱ��BITLIB.DLL�����ü�����Ϊ0�������ͷ���ռ�õļ����塣�����ʵ����ͼƬ��������ʽ��һ�ּ򵥷�������ν�ġ�ͼƬ��������ʽ�����ܹ���Ԥ�Ƚ����ĵ���ͼ������metafile����ǿ��metafile�����뵽���������Թ�������ʽʹ�õij�ʽ��