#include "stdafx.h"
#include "windows.h"
typedef BOOL (CALLBACK * MY_FUNC)();
MY_FUNC ShowWnd;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdline, int ShowCmd)
{
HMODULE dll = LoadLibrary("myLib.lib");
ShowWnd = (MY_FUNC)GetProcAddress(GetModuleHandleA("myLib.lib"), "ShowWnd");
ShowWnd();
FreeLibrary(dll);
return 0;
}
Окно из DLL
Задача - сделать lib в которой бы создавалось окно, а в основной программе вызывалась функция по созданию этого окна из lib.
Есть код (сразу скажу, что взял в инете):
Основная программа (без проверок критичных мест):
Код:
И сама lib:
Код:
#include "windows.h"
HINSTANCE hInstance;
HWND hwnd;
LRESULT CALLBACK DllWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
BOOL APIENTRY DllMain(HINSTANCE hModule,DWORD dwReason,LPVOID)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
WNDCLASS wnd;
memset(&wnd,0,sizeof(WNDCLASS));
wnd.style = CS_OWNDC|CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS|CS_GLOBALCLASS;
wnd.lpfnWndProc = (WNDPROC)DllWndProc;
wnd.hInstance = hModule;
wnd.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
wnd.lpszClassName = "DllWndClass";
wnd.lpszMenuName = NULL;
wnd.hCursor = LoadCursor(NULL,IDC_ARROW);
wnd.hIcon = NULL;
BOOL res = RegisterClass(&wnd);
hInstance = hModule;
break;
}
return 1;
}
LRESULT CALLBACK DllWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc(hwnd,msg,wParam,lParam);
}
return 0;
}
extern "C" __declspec(dllexport) BOOL ShowWnd()
{
hwnd = CreateWindowEx(WS_EX_TOPMOST,"DllWndClass","Dll Window",WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_CAPTION|WS_SYSMENU,225,175,350,250,NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,SW_SHOW);
MSG msg;
while (GetMessage(&msg,hwnd,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 1;
}
HINSTANCE hInstance;
HWND hwnd;
LRESULT CALLBACK DllWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);
BOOL APIENTRY DllMain(HINSTANCE hModule,DWORD dwReason,LPVOID)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH:
WNDCLASS wnd;
memset(&wnd,0,sizeof(WNDCLASS));
wnd.style = CS_OWNDC|CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS|CS_GLOBALCLASS;
wnd.lpfnWndProc = (WNDPROC)DllWndProc;
wnd.hInstance = hModule;
wnd.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
wnd.lpszClassName = "DllWndClass";
wnd.lpszMenuName = NULL;
wnd.hCursor = LoadCursor(NULL,IDC_ARROW);
wnd.hIcon = NULL;
BOOL res = RegisterClass(&wnd);
hInstance = hModule;
break;
}
return 1;
}
LRESULT CALLBACK DllWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc(hwnd,msg,wParam,lParam);
}
return 0;
}
extern "C" __declspec(dllexport) BOOL ShowWnd()
{
hwnd = CreateWindowEx(WS_EX_TOPMOST,"DllWndClass","Dll Window",WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_CAPTION|WS_SYSMENU,225,175,350,250,NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,SW_SHOW);
MSG msg;
while (GetMessage(&msg,hwnd,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 1;
}
lib то создает, но подключиться к нему нельзя. Ругается виндовской ошибкой:
"Приложение или боблиотека "трам-пам-пам" не являются образом программы для Window NT. Проверьте наличие установочного диска"
Кто-нибудь знает, где похожий вопрос уже рассматривался? Либо статья какая есть, тема форума?
Или, быть может, кто подскажет, что надо сделать с этим кодом, что бы все стало хорошо)
Кроме того, прототип экспортируемых из dll функций должен должен быть одинаковым и при реализации, и при исполльзовании. То есть, если у тебя в реализации ShowWnd() объявлена как extern "C" BOOL ShowWnd(), то почему при использовании она объявлена как BOOL CALLBACK ShowWnd()?
Делай, короче, проще: прототипы всех экспортируемых функций выноси в отдельный шашпошный (.h) файл, там же объяви макрос
Код:
// mylib.h
#ifdef _MYLIB_EXPORTS
#define MYLIB extern "C" __declspec(dllexport)
#else
#define MYLIB extern "C" __declspec(dllimport)
#endif
MYLIB BOOL ShowWnd();
#ifdef _MYLIB_EXPORTS
#define MYLIB extern "C" __declspec(dllexport)
#else
#define MYLIB extern "C" __declspec(dllimport)
#endif
MYLIB BOOL ShowWnd();
В файле реализации (.cpp) библиотеки перед включением шапки определяем лексему, участвующую в условии при определении макроса.
Код:
// mylib.cpp
#define _MYLIB_EXPORTS
#include "mylib.h"
MYLIB BOOL ShowWnd()
{
// далее по смыслу
}
#define _MYLIB_EXPORTS
#include "mylib.h"
MYLIB BOOL ShowWnd()
{
// далее по смыслу
}
Всё. Результат компиляции - два файла: mylib.dll и mylib.lib (конкретно в случае компиляции dll, .lib-файл никакого кода не содержит и нужен только для связывания, за подробностями - в поиск).
Дальше, в основной программе подключаем все наши дела
Код:
// main.cpp
#include "mylib.h"
#pragma comment(lib, "mylib.lib") // вот он зачем
int WINAPI _tWinMain()
{
// туда-сюда
if(!ShowWindow())
// ;
}
#include "mylib.h"
#pragma comment(lib, "mylib.lib") // вот он зачем
int WINAPI _tWinMain()
{
// туда-сюда
if(!ShowWindow())
// ;
}
Код:
// main.cpp
// Уже не нужно
// #include "mylib.h"
// #pragma comment(lib, "mylib.lib")
typedef BOOL (*ShowWndProc)();
int WINAPI _tWinMain
{
LoadLibrary(TEXT("mylib.dll"))
ShowWndProc showWnd = (ShowWndProc) GetProcAddress(GetModuleHandle(TEXT("mylib.dll")), TEXT("ShowWnd"))
if (!showWnd())
// ;
}
// Уже не нужно
// #include "mylib.h"
// #pragma comment(lib, "mylib.lib")
typedef BOOL (*ShowWndProc)();
int WINAPI _tWinMain
{
LoadLibrary(TEXT("mylib.dll"))
ShowWndProc showWnd = (ShowWndProc) GetProcAddress(GetModuleHandle(TEXT("mylib.dll")), TEXT("ShowWnd"))
if (!showWnd())
// ;
}
Спасибо огромное, выручили ;)
Есть мнение, что можно сделать тоже самое, но проще и без использования DllMain. Как - я не знаю. Подскажите?
Вы сами себя пробовали прочитать?
Вы что хотите? подключать библиотеку без точки входа? гораздо проще можно просто не использовать dll.
Передло мной поставили задачу - создать окно из dll, причем не ипользоваться ф-ию DllMain. В интернете я нашел только реализацию с DllMain, потому и спрашиваю, каким другим образом можно решить эту задачу. (dll использовать надо)
Перенести код из DllMain в ShowWnd не подходит?
[QUOTE=lifs]Перенести код из DllMain в ShowWnd не подходит?[/QUOTE]По-моему, код регистрации класса окна всё же лучше оставить в DllMain().
Цитата: Der Meister
По-моему, код регистрации класса окна всё же лучше оставить в DllMain().
Я согласен, но если для кого-то дело принципа отсутствие DllMain, то почему бы не пойти людям навстречу? Правда это немного усложнит - нужно чтобы класс регистрировался единожды, но если хотят...
[QUOTE=lifs]Я согласен, но если для кого-то дело принципа отсутствие DllMain, то почему бы не пойти людям навстречу?[/QUOTE]Без точки входа не скомпилирует. А если и скомпилирует, то не подгрузит.[QUOTE=lifs]Правда это немного усложнит - нужно чтобы класс регистрировался единожды, но если хотят...[/QUOTE]Да без разницы, функция регистрации просто вернёт FALSE при повторном вызове. Иное дело, что такое значение может быть возвращено по совершенно иным причинам. Я сомневаюсь, что озадачивающий может быть настолько неадекватным, чтобы не понять логичность такого шага...[QUOTE=Sholah_Weras]Есть мнение, что можно сделать тоже самое, но проще и без использования DllMain.[/QUOTE]Кто этот мудрец? Кажется, его кунг-фу сильнее моего... Хочу стать его учеником!
Как узнаю прием кунгфустический - обязательно поделюсь.
Цитата: Der Meister
Без точки входа не скомпилирует. А если и скомпилирует, то не подгрузит.
И скомпилирует, и подгрузит, наличие точки входа не обязательно в dll. К примеру, dll, используемые только для ресурсов, точки входа зачастую не имеют.
[QUOTE=Richter, Jeffrey]В документации Platform SDK утверждается, что DllMain должна выполнять лишь простые виды инициализации — настройку локальной памяти потока (см. главу 21), создание объектов ядра, открытие файлов и т. д. Избегайте обращений к функциям, связанным с User, Shell, ODBC, COM, RPC и сокетами (а также к функциям, которые их вызывают), потому что соответствующие DLL могут быть еще не инициализированы. Кроме того, подобные функции могут вызывать LoadLibrary(Ex) и тем самым приводить к взаимной блокировке.[/QUOTE]
взято отсюда
Цитата: Der Meister
Кто этот мудрец? Кажется, его кунг-фу сильнее моего... Хочу стать его учеником!
Шаг 1:
- Создаеш новый Win32 проект (dll, Empty Project).
- Добавляеш в него новый класс (например [SIZE=2]MyWindow[/SIZE]).
файл [SIZE=2]MyWindow.h:[/SIZE]
[SIZE=2]
Код:
[SIZE=2][COLOR=#0000ff]#pragma[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]once[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]#define[/COLOR][/SIZE][SIZE=2] EXPORT [/SIZE][SIZE=2][COLOR=#0000ff]__declspec[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#0000ff]dllexport[/COLOR][/SIZE][SIZE=2])[/SIZE]
[SIZE=2][COLOR=#0000ff]class[/COLOR][/SIZE][SIZE=2] EXPORT MyWindow[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2][COLOR=#0000ff]private[/COLOR][/SIZE][SIZE=2] :[/SIZE]
[SIZE=2]HWND hWnd;[/SIZE]
[SIZE=2]HINSTANCE hInstance; [/SIZE]
[SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][SIZE=2] Proceed([/SIZE][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][SIZE=2]);[/SIZE]
[SIZE=2][COLOR=#0000ff]public[/COLOR][/SIZE][SIZE=2]:[/SIZE]
[SIZE=2]MyWindow([/SIZE][SIZE=2][COLOR=#0000ff]const[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]wchar_t[/COLOR][/SIZE][SIZE=2]* szClassName);[/SIZE]
[SIZE=2]~MyWindow([/SIZE][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][SIZE=2]);[/SIZE]
[SIZE=2][COLOR=#0000ff]static[/COLOR][/SIZE][SIZE=2] LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);[/SIZE]
[SIZE=2]};[/SIZE]
[SIZE=2][COLOR=#0000ff]#define[/COLOR][/SIZE][SIZE=2] EXPORT [/SIZE][SIZE=2][COLOR=#0000ff]__declspec[/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#0000ff]dllexport[/COLOR][/SIZE][SIZE=2])[/SIZE]
[SIZE=2][COLOR=#0000ff]class[/COLOR][/SIZE][SIZE=2] EXPORT MyWindow[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2][COLOR=#0000ff]private[/COLOR][/SIZE][SIZE=2] :[/SIZE]
[SIZE=2]HWND hWnd;[/SIZE]
[SIZE=2]HINSTANCE hInstance; [/SIZE]
[SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][SIZE=2] Proceed([/SIZE][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][SIZE=2]);[/SIZE]
[SIZE=2][COLOR=#0000ff]public[/COLOR][/SIZE][SIZE=2]:[/SIZE]
[SIZE=2]MyWindow([/SIZE][SIZE=2][COLOR=#0000ff]const[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]wchar_t[/COLOR][/SIZE][SIZE=2]* szClassName);[/SIZE]
[SIZE=2]~MyWindow([/SIZE][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][SIZE=2]);[/SIZE]
[SIZE=2][COLOR=#0000ff]static[/COLOR][/SIZE][SIZE=2] LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);[/SIZE]
[SIZE=2]};[/SIZE]
файл MyWindow.cpp:
Код:
[SIZE=2][COLOR=#0000ff]#include[/COLOR][/SIZE][SIZE=2][COLOR=#a31515]<windows.h>[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]#include[/COLOR][/SIZE][SIZE=2][COLOR=#a31515]"MyWindow.h"[/COLOR][/SIZE]
[SIZE=2]MyWindow::MyWindow([/SIZE][SIZE=2][COLOR=#0000ff]const[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]wchar_t[/COLOR][/SIZE][SIZE=2]* szClassName)[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2]WNDCLASSEX wcex;[/SIZE]
[SIZE=2]hInstance = GetModuleHandle(L[/SIZE][SIZE=2][COLOR=#a31515]"testdll.dll"[/COLOR][/SIZE][SIZE=2]);[/SIZE]
[SIZE=2]wcex.cbSize = [/SIZE][SIZE=2][COLOR=#0000ff]sizeof[/COLOR][/SIZE][SIZE=2](WNDCLASSEX);[/SIZE]
[SIZE=2]wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;[/SIZE]
[SIZE=2]wcex.lpfnWndProc = WndProc;[/SIZE]
[SIZE=2]wcex.cbClsExtra = 0;[/SIZE]
[SIZE=2]wcex.cbWndExtra = 0;[/SIZE]
[SIZE=2]wcex.hInstance = hInstance;[/SIZE]
[SIZE=2]wcex.hIcon = LoadIcon(NULL, IDI_INFORMATION);[/SIZE]
[SIZE=2]wcex.hCursor = LoadCursor(NULL, IDC_ARROW);[/SIZE]
[SIZE=2]wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);[/SIZE]
[SIZE=2]wcex.lpszMenuName = NULL; [/SIZE]
[SIZE=2]wcex.lpszClassName = szClassName;[/SIZE]
[SIZE=2]wcex.hIconSm = LoadIcon(NULL, IDI_INFORMATION);[/SIZE]
[SIZE=2]RegisterClassEx(&wcex);[/SIZE]
[SIZE=2]hWnd = CreateWindow(szClassName, L[/SIZE][SIZE=2][COLOR=#a31515]"Test Window"[/COLOR][/SIZE][SIZE=2], WS_OVERLAPPEDWINDOW,[/SIZE]
[SIZE=2]CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);[/SIZE]
[SIZE=2]ShowWindow(hWnd, SW_NORMAL);[/SIZE]
[SIZE=2]UpdateWindow(hWnd);[/SIZE]
[SIZE=2]Proceed();[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2]MyWindow::~MyWindow([/SIZE][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][SIZE=2])[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][SIZE=2] MyWindow::Proceed()[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2]MSG msg;[/SIZE]
[SIZE=2][COLOR=#0000ff]while[/COLOR][/SIZE][SIZE=2] (GetMessage(&msg, NULL, 0, 0))[/SIZE]
[SIZE=2]{ [/SIZE]
[SIZE=2]TranslateMessage(&msg);[/SIZE]
[SIZE=2]DispatchMessage(&msg); [/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2]LRESULT CALLBACK MyWindow::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] wmId, wmEvent;[/SIZE]
[SIZE=2]PAINTSTRUCT ps;[/SIZE]
[SIZE=2]HDC hdc;[/SIZE]
[SIZE=2][COLOR=#0000ff]switch[/COLOR][/SIZE][SIZE=2] (message)[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2][COLOR=#0000ff]case[/COLOR][/SIZE][SIZE=2] WM_LBUTTONDBLCLK:[/SIZE]
[SIZE=2]MessageBox(hWnd, L[/SIZE][SIZE=2][COLOR=#a31515]"Test Window from dll."[/COLOR][/SIZE][SIZE=2], L[/SIZE][SIZE=2][COLOR=#a31515]"MyWindow"[/COLOR][/SIZE][SIZE=2], NULL);[/SIZE]
[SIZE=2][COLOR=#0000ff]break[/COLOR][/SIZE][SIZE=2];[/SIZE]
[SIZE=2][COLOR=#0000ff]case[/COLOR][/SIZE][SIZE=2] WM_PAINT:[/SIZE]
[SIZE=2]hdc = BeginPaint(hWnd, &ps);[/SIZE]
[SIZE=2]EndPaint(hWnd, &ps);[/SIZE]
[SIZE=2][COLOR=#0000ff]break[/COLOR][/SIZE][SIZE=2];[/SIZE]
[SIZE=2][COLOR=#0000ff]case[/COLOR][/SIZE][SIZE=2] WM_DESTROY:[/SIZE]
[SIZE=2]PostQuitMessage(0);[/SIZE]
[SIZE=2][COLOR=#0000ff]break[/COLOR][/SIZE][SIZE=2];[/SIZE]
[SIZE=2][COLOR=#0000ff]default[/COLOR][/SIZE][SIZE=2]:[/SIZE]
[SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][SIZE=2] DefWindowProc(hWnd, message, wParam, lParam);[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][SIZE=2] 0;[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2][COLOR=#0000ff]#include[/COLOR][/SIZE][SIZE=2][COLOR=#a31515]"MyWindow.h"[/COLOR][/SIZE]
[SIZE=2]MyWindow::MyWindow([/SIZE][SIZE=2][COLOR=#0000ff]const[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]wchar_t[/COLOR][/SIZE][SIZE=2]* szClassName)[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2]WNDCLASSEX wcex;[/SIZE]
[SIZE=2]hInstance = GetModuleHandle(L[/SIZE][SIZE=2][COLOR=#a31515]"testdll.dll"[/COLOR][/SIZE][SIZE=2]);[/SIZE]
[SIZE=2]wcex.cbSize = [/SIZE][SIZE=2][COLOR=#0000ff]sizeof[/COLOR][/SIZE][SIZE=2](WNDCLASSEX);[/SIZE]
[SIZE=2]wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;[/SIZE]
[SIZE=2]wcex.lpfnWndProc = WndProc;[/SIZE]
[SIZE=2]wcex.cbClsExtra = 0;[/SIZE]
[SIZE=2]wcex.cbWndExtra = 0;[/SIZE]
[SIZE=2]wcex.hInstance = hInstance;[/SIZE]
[SIZE=2]wcex.hIcon = LoadIcon(NULL, IDI_INFORMATION);[/SIZE]
[SIZE=2]wcex.hCursor = LoadCursor(NULL, IDC_ARROW);[/SIZE]
[SIZE=2]wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);[/SIZE]
[SIZE=2]wcex.lpszMenuName = NULL; [/SIZE]
[SIZE=2]wcex.lpszClassName = szClassName;[/SIZE]
[SIZE=2]wcex.hIconSm = LoadIcon(NULL, IDI_INFORMATION);[/SIZE]
[SIZE=2]RegisterClassEx(&wcex);[/SIZE]
[SIZE=2]hWnd = CreateWindow(szClassName, L[/SIZE][SIZE=2][COLOR=#a31515]"Test Window"[/COLOR][/SIZE][SIZE=2], WS_OVERLAPPEDWINDOW,[/SIZE]
[SIZE=2]CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);[/SIZE]
[SIZE=2]ShowWindow(hWnd, SW_NORMAL);[/SIZE]
[SIZE=2]UpdateWindow(hWnd);[/SIZE]
[SIZE=2]Proceed();[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2]MyWindow::~MyWindow([/SIZE][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][SIZE=2])[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][SIZE=2] MyWindow::Proceed()[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2]MSG msg;[/SIZE]
[SIZE=2][COLOR=#0000ff]while[/COLOR][/SIZE][SIZE=2] (GetMessage(&msg, NULL, 0, 0))[/SIZE]
[SIZE=2]{ [/SIZE]
[SIZE=2]TranslateMessage(&msg);[/SIZE]
[SIZE=2]DispatchMessage(&msg); [/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2]LRESULT CALLBACK MyWindow::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] wmId, wmEvent;[/SIZE]
[SIZE=2]PAINTSTRUCT ps;[/SIZE]
[SIZE=2]HDC hdc;[/SIZE]
[SIZE=2][COLOR=#0000ff]switch[/COLOR][/SIZE][SIZE=2] (message)[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2][COLOR=#0000ff]case[/COLOR][/SIZE][SIZE=2] WM_LBUTTONDBLCLK:[/SIZE]
[SIZE=2]MessageBox(hWnd, L[/SIZE][SIZE=2][COLOR=#a31515]"Test Window from dll."[/COLOR][/SIZE][SIZE=2], L[/SIZE][SIZE=2][COLOR=#a31515]"MyWindow"[/COLOR][/SIZE][SIZE=2], NULL);[/SIZE]
[SIZE=2][COLOR=#0000ff]break[/COLOR][/SIZE][SIZE=2];[/SIZE]
[SIZE=2][COLOR=#0000ff]case[/COLOR][/SIZE][SIZE=2] WM_PAINT:[/SIZE]
[SIZE=2]hdc = BeginPaint(hWnd, &ps);[/SIZE]
[SIZE=2]EndPaint(hWnd, &ps);[/SIZE]
[SIZE=2][COLOR=#0000ff]break[/COLOR][/SIZE][SIZE=2];[/SIZE]
[SIZE=2][COLOR=#0000ff]case[/COLOR][/SIZE][SIZE=2] WM_DESTROY:[/SIZE]
[SIZE=2]PostQuitMessage(0);[/SIZE]
[SIZE=2][COLOR=#0000ff]break[/COLOR][/SIZE][SIZE=2];[/SIZE]
[SIZE=2][COLOR=#0000ff]default[/COLOR][/SIZE][SIZE=2]:[/SIZE]
[SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][SIZE=2] DefWindowProc(hWnd, message, wParam, lParam);[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][SIZE=2] 0;[/SIZE]
[SIZE=2]}[/SIZE]
- Компилиш dll (например testdll.dll)
Шаг 2:
- Создаеш проект (Windows Application, Empty project)
- Добавляеш файл (*.cpp):
Код:
[SIZE=2][COLOR=#0000ff]#include[/COLOR][/SIZE][SIZE=2][COLOR=#a31515]<windows.h>[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]#include[/COLOR][/SIZE][SIZE=2][COLOR=#a31515]"../testdll/MyWindow.h"[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]#pragma[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]comment[/COLOR][/SIZE][SIZE=2] ([/SIZE][SIZE=2][COLOR=#0000ff]lib[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#a31515]"testdll.lib"[/COLOR][/SIZE][SIZE=2])[/SIZE]
[SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] APIENTRY WinMain(HINSTANCE hInstance,[/SIZE]
[SIZE=2]HINSTANCE hPrevInstance,[/SIZE]
[SIZE=2]LPSTR lpCmdLine,[/SIZE]
[SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] nCmdShow)[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2]MyWindow * wnd = [/SIZE][SIZE=2][COLOR=#0000ff]new[/COLOR][/SIZE][SIZE=2] MyWindow(L[/SIZE][SIZE=2][COLOR=#a31515]"TestMyWindowCLS"[/COLOR][/SIZE][SIZE=2]);[/SIZE]
[SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][SIZE=2] 0;[/SIZE]
[SIZE=2]}[/SIZE]
[SIZE=2][COLOR=#0000ff]#include[/COLOR][/SIZE][SIZE=2][COLOR=#a31515]"../testdll/MyWindow.h"[/COLOR][/SIZE]
[SIZE=2][COLOR=#0000ff]#pragma[/COLOR][/SIZE][SIZE=2][COLOR=#0000ff]comment[/COLOR][/SIZE][SIZE=2] ([/SIZE][SIZE=2][COLOR=#0000ff]lib[/COLOR][/SIZE][SIZE=2], [/SIZE][SIZE=2][COLOR=#a31515]"testdll.lib"[/COLOR][/SIZE][SIZE=2])[/SIZE]
[SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] APIENTRY WinMain(HINSTANCE hInstance,[/SIZE]
[SIZE=2]HINSTANCE hPrevInstance,[/SIZE]
[SIZE=2]LPSTR lpCmdLine,[/SIZE]
[SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][SIZE=2] nCmdShow)[/SIZE]
[SIZE=2]{[/SIZE]
[SIZE=2]MyWindow * wnd = [/SIZE][SIZE=2][COLOR=#0000ff]new[/COLOR][/SIZE][SIZE=2] MyWindow(L[/SIZE][SIZE=2][COLOR=#a31515]"TestMyWindowCLS"[/COLOR][/SIZE][SIZE=2]);[/SIZE]
[SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][SIZE=2] 0;[/SIZE]
[SIZE=2]}[/SIZE]
зы: путь к [COLOR=#a31515]MyWindow.h [COLOR=black]и[/COLOR] testdll.lib [/COLOR][COLOR=black]ставиш свои[/COLOR]
- компилиш.
Шаг 3:
- Постигаеш Кунг-Фу.
[/SIZE]
Можно гораздо проще: взять в руки проект MFC extension dll, добавить в ресурсы диалог, щёлкнуть на нём правой кнопкой, выбрать Add сlass и не париться с шаолинем. Но это не то пальто...