BOOL WINAPI DllEntryPoint( HINSTANCE hinstDLL , DWORD fdwReason , LPVOID lpvReserved );hinstDll には、この DLL のインスタンスが格納されています
| 定数 | 解説 | 
|---|---|
| DLL_PROCESS_ATTACH | DLL が、現在のプロセスのアドレス空間にアタッチしようとしていることを示します プロセスの起動時や、プロセスが LoadLibrary() 関数を呼び出したときに このフラグが通知されます  | 
| DLL_THREAD_ATTACH | 現在のプロセスが、新しいスレッドを作成しようとしていることを示します 既存のスレッドが、新しくロードされた DLL に対して エントリポイントを呼び出すことはありません  | 
| DLL_THREAD_DETACH | 既存のスレッドが終了しようとしていることを示します DLL_THREAD_ATTACH が通知されていないのに DLL_THREAD_DETACH が通知されることがあります たとえば、スレッドの起動後に LoadLibrary() 関数が呼び出された場合です  | 
| DLL_PROCESS_DETACH | DLL が、呼び出し側プロセスのアドレス空間から デタッチしようとしていることを示します プロセスが FreeLibrary() 関数を呼び出したときや 正常終了したときに、このフラグが通知されます なお、DLL のデタッチ時に、プロセス内の個々のスレッドに対する DLL_THREAD_DETACH が通知されることはありません  | 
/*dll_test.c*/
#include <windows.h>
#define PRC_ATT TEXT("DLL が読み込まれました")
#define PRC_DET TEXT("DLL が解放されました")
#define TRD_ATT TEXT("既存プロセスが新しいスレッドを作成しています")
#define TRD_DET TEXT("既存のスレッドが終了しようとしています")
#define TITLE TEXT("Kitty on your lap")
int WINAPI DllEntryPoint(HINSTANCE hInstance , DWORD fdwReason , PVOID pvReserved) {
	switch(fdwReason) {
	case DLL_PROCESS_ATTACH:
		MessageBox(NULL , PRC_ATT , TITLE , MB_OK);
		break;
	case DLL_PROCESS_DETACH:
		MessageBox(NULL , PRC_DET , TITLE , MB_OK);
		break;
	case DLL_THREAD_ATTACH:
		MessageBox(NULL , TRD_ATT , TITLE , MB_OK);
		break;
	case DLL_THREAD_DETACH:
		MessageBox(NULL , TRD_DET , TITLE , MB_OK);
	}
	return TRUE;
}
WinMain() 関数がないということを除けば、通常の Win32 API プログラムと変わりません#include <windows.h>
LRESULT CALLBACK WndProc(HWND hWnd , UINT msg , WPARAM wp , LPARAM lp) {
	static HINSTANCE hDLL;
	switch (msg) {
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	case WM_CREATE:
		hDLL = LoadLibrary(TEXT("DLL_TEST.DLL"));
		return 0;
	case WM_LBUTTONUP:
		if (hDLL) FreeLibrary(hDLL);
		return 0;
	}
	return DefWindowProc(hWnd , msg , wp , lp);
}
int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
			PSTR lpCmdLine , int nCmdShow) {
	HWND hWnd;
	MSG msg;
	WNDCLASS winc;
	winc.style 		= CS_HREDRAW | CS_VREDRAW;
	winc.lpfnWndProc	= WndProc;
	winc.cbClsExtra	= winc.cbWndExtra	= 0;
	winc.hInstance		= hInstance;
	winc.hIcon		= LoadIcon(NULL , IDI_APPLICATION);
	winc.hCursor		= LoadCursor(NULL , IDC_ARROW);
	winc.hbrBackground	= GetStockObject(WHITE_BRUSH);
	winc.lpszMenuName	= NULL;
	winc.lpszClassName	= TEXT("KITTY");
	if (!RegisterClass(&winc)) return 1;
	hWnd = CreateWindow(
			TEXT("KITTY") , TEXT("Kitty on your lap") ,
			WS_OVERLAPPEDWINDOW | WS_VISIBLE ,
			CW_USEDEFAULT , CW_USEDEFAULT ,
			CW_USEDEFAULT , CW_USEDEFAULT ,
			NULL , NULL , hInstance , NULL
	);
	if (hWnd == NULL) return 1;
	while (GetMessage(&msg , NULL , 0 , 0 )) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}
このプログラムは、DLL_TEST.DLL ファイルを実行時に読み込み/*test.h*/ #ifdef __cplusplus #define DLL_EXPORT extern "C" __declspec (dllexport) #else #define DLL_EXPORT __declspec (dllexport) #endif DLL_EXPORT BOOL CALLBACK GetCenter(LPRECT , LPRECT);__cplusplus という定数は、Microsoft 固有の組み込みマクロです
/*dll_test.c*/
#include <windows.h>
#include "test.h"
int WINAPI DllEntryPoint(HINSTANCE hInstance , DWORD fdwReason , PVOID pvReserved) {
	return TRUE;
}
DLL_EXPORT BOOL CALLBACK GetCenter(LPRECT lpParent , LPRECT lpChild) {
	if (lpParent->right < lpChild->right || lpParent->bottom < lpChild->bottom)
		return FALSE;
	lpChild->left = lpParent->right / 2 - lpChild->right / 2;
	lpChild->top = lpParent->bottom / 2 - lpChild->bottom / 2;
	lpChild->right += lpChild->left;
	lpChild->bottom += lpChild->top;
	return TRUE;
}
これをコンパイルすれば、DLL は完成です#include <windows.h>
#include "test.h"
LRESULT CALLBACK WndProc(HWND hWnd , UINT msg , WPARAM wp , LPARAM lp) {
	HDC hdc;
	PAINTSTRUCT ps;
	RECT rectParent , rectChild;
	switch (msg) {
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	case WM_PAINT:
		rectChild.right = 200;
		rectChild.bottom = 100;
		GetClientRect(hWnd , &rectParent);
		hdc = BeginPaint(hWnd , &ps);
		if (!GetCenter(&rectParent , &rectChild))
			Rectangle(hdc , 0 , 0 ,
				rectParent.right , rectParent.bottom);
		else Rectangle(hdc , rectChild.left , rectChild.top ,
				rectChild.right , rectChild.bottom);
		EndPaint(hWnd , &ps);
	}
	return DefWindowProc(hWnd , msg , wp , lp);
}
int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
			PSTR lpCmdLine , int nCmdShow) {
	HWND hWnd;
	MSG msg;
	WNDCLASS winc;
	winc.style 		= CS_HREDRAW | CS_VREDRAW;
	winc.lpfnWndProc	= WndProc;
	winc.cbClsExtra	= winc.cbWndExtra	= 0;
	winc.hInstance		= hInstance;
	winc.hIcon		= LoadIcon(NULL , IDI_APPLICATION);
	winc.hCursor		= LoadCursor(NULL , IDC_ARROW);
	winc.hbrBackground	= GetStockObject(WHITE_BRUSH);
	winc.lpszMenuName	= NULL;
	winc.lpszClassName	= TEXT("KITTY");
	if (!RegisterClass(&winc)) return 1;
	hWnd = CreateWindow(
			TEXT("KITTY") , TEXT("Kitty on your lap") ,
			WS_OVERLAPPEDWINDOW | WS_VISIBLE ,
			CW_USEDEFAULT , CW_USEDEFAULT ,
			CW_USEDEFAULT , CW_USEDEFAULT ,
			NULL , NULL , hInstance , NULL
	);
	if (hWnd == NULL) return 1;
	while (GetMessage(&msg , NULL , 0 , 0 )) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}

#include <windows.h>
#include "test.h"
LRESULT CALLBACK WndProc(HWND hWnd , UINT msg , WPARAM wp , LPARAM lp) {
	HDC hdc;
	PAINTSTRUCT ps;
	RECT rectParent , rectChild;
	static FARPROC GetCenter , Rectangle;
	switch (msg) {
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	case WM_CREATE:
		GetCenter = GetProcAddress(
			LoadLibrary(TEXT("DLL_TEST.DLL")) , TEXT("GetCenter"));
		Rectangle = GetProcAddress(
			LoadLibrary(TEXT("GDI32.DLL")) , TEXT("Rectangle"));
		return 0;
	case WM_PAINT:
		rectChild.right = 200;
		rectChild.bottom = 100;
		GetClientRect(hWnd , &rectParent);
		hdc = BeginPaint(hWnd , &ps);
		if (!GetCenter(&rectParent , &rectChild))
			Rectangle(hdc , 0 , 0 ,
				rectParent.right , rectParent.bottom);
		else Rectangle(hdc , rectChild.left , rectChild.top ,
				rectChild.right , rectChild.bottom);
		EndPaint(hWnd , &ps);
	}
	return DefWindowProc(hWnd , msg , wp , lp);
}
int WINAPI WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance ,
			PSTR lpCmdLine , int nCmdShow) {
	HWND hWnd;
	MSG msg;
	WNDCLASS winc;
	winc.style 		= CS_HREDRAW | CS_VREDRAW;
	winc.lpfnWndProc	= WndProc;
	winc.cbClsExtra	= winc.cbWndExtra	= 0;
	winc.hInstance		= hInstance;
	winc.hIcon		= LoadIcon(NULL , IDI_APPLICATION);
	winc.hCursor		= LoadCursor(NULL , IDC_ARROW);
	winc.hbrBackground	= GetStockObject(WHITE_BRUSH);
	winc.lpszMenuName	= NULL;
	winc.lpszClassName	= TEXT("KITTY");
	if (!RegisterClass(&winc)) return 1;
	hWnd = CreateWindow(
			TEXT("KITTY") , TEXT("Kitty on your lap") ,
			WS_OVERLAPPEDWINDOW | WS_VISIBLE ,
			CW_USEDEFAULT , CW_USEDEFAULT ,
			CW_USEDEFAULT , CW_USEDEFAULT ,
			NULL , NULL , hInstance , NULL
	);
	if (hWnd == NULL) return 1;
	while (GetMessage(&msg , NULL , 0 , 0 )) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}
このプログラムは、先ほどの DLL_TEST.DLL を用いますBOOL WINAPI DllEntryPoint( HINSTANCE hinstDLL , DWORD fdwReason , LPVOID lpvReserved );DLL のエントリーポイント関数です
| 定数 | 解説 | 
|---|---|
| DLL_PROCESS_ATTACH | DLL が、現在のプロセスのアドレス空間にアタッチしようとしていることを示します プロセスの起動時や、プロセスが LoadLibrary() 関数を呼び出したときに このフラグが通知されます  | 
| DLL_THREAD_ATTACH | 現在のプロセスが、新しいスレッドを作成しようとしていることを示します 既存のスレッドが、新しくロードされた DLL に対して エントリポイントを呼び出すことはありません  | 
| DLL_THREAD_DETACH | 既存のスレッドが終了しようとしていることを示します DLL_THREAD_ATTACH が通知されていないのに DLL_THREAD_DETACH が通知されることがあります たとえば、スレッドの起動後に LoadLibrary() 関数が呼び出された場合です  | 
| DLL_PROCESS_DETACH | DLL が、呼び出し側プロセスのアドレス空間から デタッチしようとしていることを示します プロセスが FreeLibrary() 関数を呼び出したときや 正常終了したときに、このフラグが通知されます なお、DLL のデタッチ時に、プロセス内の個々のスレッドに対する DLL_THREAD_DETACH が通知されることはありません  |