Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Создание окна, как вызов функции из DLL....  (Прочитано 26111 раз)
0 Пользователей и 1 Гость смотрят эту тему.
sxd
Участник

ru
Offline Offline

« : 28-02-2007 17:43 » 

Привет Всем! Решил написать прогу которая при запуске выводит онко на котором 3 радио кнопки и кнопка Ok! - Это не проблема, после выбора соответствующей радиокнопки и нажатии на кнопку Ok! программа (в зависимости от того какую радиокнопку (переключатель) я выбрал) загружает одну из 3-х DLL, например:
1okno.dll,
2okno.dll,
3okno.dll,
но dll-ки не простые: хотел бы чтоб при вызове некоторой функции из них образовывалось окно, с тремя радиокнопками и кнопкой далее, нажав которую считалась инфа с радиокнопок и это окно закрылось и открылось следущее и т.д. 3 окна. Тобишь примерно как мастер установки любой программы, далее, далее, далее...
Вот проблема возникла...
При вызове из Dll своей функции происходит ошибка... Вообще можно ли хоть как-то вызвать создание окна из DLL и использовать функцию обработки сообщений окна которая находится в exe файле, т.е. окно создать Dll, а обрабатывать сообщения от него exe-ой, спасибо!
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #1 : 28-02-2007 20:46 » 

sxd, Побольше информации нужно.
1. Желательно привести в каком компиляторе и с применением каких библиотек создаются окна?
2. Исходный код вызова функций и как функция оформлена в DLL?

Отсюда уже можно плесать. Я лично вызывал и делал такое. Но я делал на чистом WinAPI. Кстати там нужно было указывать в стилях класса окна, что его нужно использовать глобально. Так как instance основной программы и Dll разные.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #2 : 01-03-2007 09:37 » 

Я делал такое на MFC - геморр ещё тот.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Diletant
Помогающий

de
Offline Offline

« Ответ #3 : 01-03-2007 12:33 » 

Строго говоря, в мастере установки программ обычно используется разновидность Таб-контрола. Т.е. в ничего нового не создается и не удаляется..
Что же каксается собственно задачи, то прежде чем обрабатывать сообщения окна, нужно как минимум, иметь его handle и вообще знать, что окно создано.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #4 : 01-03-2007 12:41 » 

На самом деле у этого "явления" есть терминология - одно окно называется PropertyPage, а объект который объединяет и управляет этими окнами называется Property Sheet. Как правило, используются три типа:
1. Tab (переключение корешков)
2. Wizard (кнопки Prev Next) - используется, когда важна строгая очерёдность.
3. Tree - при сложных структурах

Проблема загрузки окна из ДЛЛ связана так же ещё и с распределением ресурсов, между ЕХЕ и ДЛЛ. Но это всё возможно.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
sxd
Участник

ru
Offline Offline

« Ответ #5 : 03-03-2007 18:03 » 

sxd, Побольше информации нужно.
1. Желательно привести в каком компиляторе и с применением каких библиотек создаются окна?
2. Исходный код вызова функций и как функция оформлена в DLL?

Отсюда уже можно плесать. Я лично вызывал и делал такое. Но я делал на чистом WinAPI. Кстати там нужно было указывать в стилях класса окна, что его нужно использовать глобально. Так как instance основной программы и Dll разные.

Я тоже пишу на чистом С++ в VC++. Но пока никак, так как не получается вызвать функцию из Dll, которая создаст окно, а также обрабатывать его сообщения в программе это вообще непонятно... некая функция которая как-то связана с окном, которое создано "левой функцией" из DLL. Gjvjubnt gkbp!!! = "помогите пожалуйста"
« Последнее редактирование: 03-03-2007 18:18 от Джон » Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #6 : 04-03-2007 15:40 » 

Когда загружаеш библиотеку. Можно вызвать строго оговоренную функцию этой библиотеки. Например такого вида
Код:
void stdcall RegisterAll ( HINSTANCE inst);
В этой функции регистрируеш в системе, все классы окон, которые будут описаны в библиотеке. При этом при регистрации классов, лучше использовать Instance головного модуля программы. меньше головных болей.
Все, теперь когда тебе нужно вызвать следуюшее окно. Просто создаеш окно в своей главной программе с использованием имен, уже ранее зарегистрированных классов.

Лучше дай код. Потому что "Я тоже пишу на чистом С++" подрузомевает многие веши. Например, используеш ли ты классы самого С++?
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
sxd
Участник

ru
Offline Offline

« Ответ #7 : 04-03-2007 20:03 » 

"используеш ли ты классы самого С++?" не я не использую классы самого С++, окно из DLL я вызвал, но сообщения от окна обрабатываю в самой DLL, а хочу обрабатывать их в EXE.
Вот мой код DLL:

Код:
#include "stdafx.h"
#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;
}

И код EXE:

Код:
#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("dll.dll");

ShowWnd = (MY_FUNC)GetProcAddress(GetModuleHandleA("dll.dll"), "ShowWnd");
ShowWnd();

FreeLibrary(dll);
return 0;
}

Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #8 : 04-03-2007 20:16 » 

Это
Код:
while (GetMessage(&msg,hwnd,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Можно и нужно вынести в основной модуль.

При регистрации класса нужно добавить стиль CS_GLOBALCLASS. Для чего это нужно, описано здесь http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windowclasses/aboutwindow.asp
Теперь просто открываеш несколько библиотек. Происходит автоматическая регистрация всех классов. В главном модуле затем можно создавать соответствуюшие окна по именам ранее зарегистрированных классов.

Собственно так и сделаны все компоненты самой винды.
« Последнее редактирование: 04-03-2007 20:18 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
sxd
Участник

ru
Offline Offline

« Ответ #9 : 05-03-2007 15:48 » 

Так обо всём по порядку...

Код:
while (GetMessage(&msg,hwnd,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Этот код перенести в EXE, но я привёл EXE самый простой вариант, а в реальности у меня этот код присутствует в конце функции WinMain(), а также не понятно куда перенести:

Код:
LRESULT CALLBACK DllWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);

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;
}
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #10 : 06-03-2007 12:51 » 

DllWndProc оставляеш в своей DLL. Ее можно не делать экспортируемой функцией. Эта функция, обработчик всех сообшений, идуших к твоему компоненту. Только вот это PostQuitMessage (0); убери со всех своих компонентах, определенных в Dll. Так как эта функция посылает приложению WM_QUITE. Что вызывает выход из цикла опроса очереди сообшений и соответственно выходу из программы. Лучше вызов этой функции осушествлять в обработчике сообшений главного окна твоего приложения.

Чтобы настраивать твою компоненту, обрабатывай сообшение WM_CREATE. Только обрати внимание на
Цитата
Return Value

    If an application processes this message, it should return zero to continue creation of the window. If the application returns –1, the window is destroyed and the CreateWindowEx or CreateWindow function returns a NULL handle.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
sxd
Участник

ru
Offline Offline

« Ответ #11 : 06-03-2007 17:51 » 

Привет Finch! Убрал как сказал цикл обработки сообщений и обработчик на WM_DESTROY:

Код:
#include "stdafx.h"
#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)
{
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);

return 1;
}

А в DLL на WM_CREATE (вызываемое при создании окна не понял, ведь это сообщение приходит от главного окна при создании от EXE, а мне то надо тогда окно от DLL):

Код:
#include "stdafx.h"
#include <windows.h>

LRESULT CALLBACK WindowFunc(HWND, UINT,WPARAM,LPARAM);
char szWinName[] = "MyApp";

typedef BOOL (CALLBACK * MY_FUNC)();
MY_FUNC ShowWnd;

int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR lpszArgs, int nWinMode)
{
HWND hwnd;
MSG msg;
WNDCLASSEX wcl;

wcl.hInstance = hThisInst;
wcl.lpszClassName = szWinName;
wcl.lpfnWndProc = WindowFunc;
wcl.style = 0;
wcl.cbSize = sizeof(WNDCLASSEX);
wcl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcl.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
wcl.hCursor = LoadCursor(NULL, IDC_ARROW);
wcl.lpszMenuName = NULL;
wcl.cbClsExtra = 0;
wcl.cbWndExtra = 0;
wcl.hbrBackground = (HBRUSH) GetStockObject(3);
if(!RegisterClassEx(&wcl)) return 0;

hwnd = CreateWindow(szWinName,
"Windows 95 sceleton",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
HWND_DESKTOP,
NULL,
hThisInst,
NULL
);
ShowWindow(hwnd, nWinMode);
UpdateWindow(hwnd);

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

LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;

HMODULE dll = LoadLibrary("dll.dll");//добавленно загрузка

switch(message)
{
case WM_CREATE://добавленно при создании окна
ShowWnd = (MY_FUNC)GetProcAddress(GetModuleHandleA("dll.dll"), "ShowWnd");
ShowWnd();
break;

case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);

EndPaint(hwnd, &ps);
break;

case WM_DESTROY:
FreeLibrary(dll);//добавленно освобождение
PostQuitMessage(0);
break;

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

Finch я всё правильно понял.
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #12 : 07-03-2007 13:21 » 

Эту строчку
Код:
HMODULE dll = LoadLibrary("dll.dll");//добавленно загрузка

вынеси куда нибудь в начало WinMain. Так как при обработке любого события у тебя все время будет она отрабатыватьсь. Это конечно не критично, просто будет увеличиваться счетчик загрузки библиотеки, но это просто будет занимать время.

Кстати
Код:
if(!RegisterClassEx(&wcl)) return 0;

hwnd = CreateWindow(szWinName,
Ты регистрируеш расширенный класс. А применяеш в стандартном виде.

Все просматривал глазами. Просто сейчас пока нету возможности прогонки кода на компе.
« Последнее редактирование: 07-03-2007 13:23 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
sxd
Участник

ru
Offline Offline

« Ответ #13 : 07-03-2007 17:55 » 

Эту строчку
Код:
HMODULE dll = LoadLibrary("dll.dll");//добавленно загрузка

вынеси куда нибудь в начало WinMain. Так как при обработке любого события у тебя все время будет она отрабатыватьсь. Это конечно не критично, просто будет увеличиваться счетчик загрузки библиотеки, но это просто будет занимать время.

Кстати
Код:
if(!RegisterClassEx(&wcl)) return 0;

hwnd = CreateWindow(szWinName,
Ты регистрируеш расширенный класс. А применяеш в стандартном виде.

Все просматривал глазами. Просто сейчас пока нету возможности прогонки кода на компе.

Finch понимаешь мне надо в зависимости от того какой переключатель я выбрал при нажатии на кнопку отобразилось окно из первой или второй DLL:

Код:
#include "stdafx.h"
#include <windows.h>

LRESULT CALLBACK WindowFunc(HWND, UINT,WPARAM,LPARAM);
char szWinName[] = "MyApp";

typedef BOOL (CALLBACK * MY_FUNC)();
MY_FUNC ShowWnd;

HWND hwnd;
[b]HWND hOneBox;
HWND hTwoBox;
HWND hButton;

HMODULE dll_1;
HMODULE dll_2;[/b]

int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR lpszArgs, int nWinMode)
{
MSG msg;
WNDCLASSEX wcl;

[b]dll_1 = LoadLibrary("dll_1.dll");
dll_2 = LoadLibrary("dll_2.dll");[/b]

wcl.hInstance = hThisInst;
wcl.lpszClassName = szWinName;
wcl.lpfnWndProc = WindowFunc;
wcl.style = 0;
wcl.cbSize = sizeof(WNDCLASSEX);
wcl.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcl.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
wcl.hCursor = LoadCursor(NULL, IDC_ARROW);
wcl.lpszMenuName = NULL;
wcl.cbClsExtra = 0;
wcl.cbWndExtra = 0;
wcl.hbrBackground = (HBRUSH) GetStockObject(3);
if(!RegisterClassEx(&wcl)) return 0;

hwnd = CreateWindow(szWinName,
"Windows 95 sceleton",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
HWND_DESKTOP,
NULL,
hThisInst,
NULL
);
ShowWindow(hwnd, nWinMode);
UpdateWindow(hwnd);

[b]hOneBox = CreateWindow("BUTTON", "Переключатель 1", WS_VISIBLE|WS_CHILD|BS_AUTORADIOBUTTON, 300,60,200,20, hwnd, NULL, hThisInst, NULL); 
ShowWindow(hOneBox,SW_SHOW), UpdateWindow(hOneBox);

hTwoBox = CreateWindow("BUTTON", "Переключатель 2", WS_VISIBLE|WS_CHILD|BS_AUTORADIOBUTTON, 300,90,200,20, hwnd, NULL, hThisInst, NULL);
ShowWindow(hTwoBox,SW_SHOW), UpdateWindow(hTwoBox);

hButton = CreateWindow("BUTTON", "Кнопка", WS_VISIBLE|WS_CHILD, 300,150,150,30, hwnd, NULL, hThisInst, NULL);
ShowWindow(hButton, SW_SHOW), UpdateWindow(hButton);[/b]

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

LRESULT CALLBACK WindowFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;

switch(message)
{
[b]case WM_COMMAND:
switch (LOWORD(wParam))
{
case BN_CLICKED:
if (hButton == (HWND)lParam)
if (SendMessage (hOneBox, BM_GETSTATE, 0, 0) == TRUE)//если выбрал первый переключатель и нажал на кнопку
{
ShowWnd = (MY_FUNC)GetProcAddress(GetModuleHandleA("dll_1.dll"), "ShowWnd");//загрузить окно из первой DLL
ShowWnd();
}
if (SendMessage (hTwoBox, BM_GETSTATE, 0, 0) == TRUE)//если выбрал вторую переключатель и нажал на кнопку
{
ShowWnd = (MY_FUNC)GetProcAddress(GetModuleHandleA("dll_2.dll"), "ShowWnd");//загрузить окно из второй DLL
ShowWnd();
}
}
break;[/b]

case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
EndPaint(hwnd, &ps);
break;

case WM_DESTROY:
FreeLibrary(dll_1);
FreeLibrary(dll_2);
PostQuitMessage(0);
break;

default:
        return DefWindowProc(hwnd, message, wParam, lParam);
}
        return 0;
}
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #14 : 08-03-2007 12:38 » 

Конечно можно еше оптимизировать код. Но думаю в таком виде, он должен работать.

Только вот такая бяка у тебя будет. Главное окно никем не блокируется. Следовательно, пользователь может спокойно перейти на главное окно и вызвать несколько раз окна.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
sxd
Участник

ru
Offline Offline

« Ответ #15 : 08-03-2007 17:52 » 

Да это ты точно подметил! Может в обработчике события нажатия на кнопку, после загрузки DLL поставить SendMessage (hwnd, WM_CLOSE, 0, 0), но тогда прога закроется, а SendMessage (hwnd, SW_SHOW, 0, 0), использовать не хочу это как глупо, но наверное больше ни чего не останется как использовать SW_SHOW. (((((

А вот хотел ещё спросить как обрабатывать нажатие в окне созданном функцией из DLL, я всё никак не пойму как можно обработать сообщения в EXE тогда как в DLL есть своя функция обработки сообщений?

Даже для простого примера пробовал в функции обработки сообщений DLL, обработать нажатие на кнопку, и удивительно - не получилось! А мне ещё к тому же это надо сделать в программе.
Код неудачной DLL:
Код:
#include "stdafx.h"
#include "windows.h"

HINSTANCE hInstance;
HWND hwnd;
HWND hButton;

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_COMMAND:
switch (LOWORD(wParam))
{
case BN_CLICKED:
if (hButton == (HWND)lParam)
MessageBox (0,"Кнопка нажата!","Сообщение!",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);

hButton = CreateWindow("BUTTON", "Кнопка", WS_VISIBLE|WS_CHILD, 100,100,150,30, hwnd, NULL, hInstance, NULL);
ShowWindow(hButton, SW_SHOW), UpdateWindow(hButton);

return 1;
}
Записан
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #16 : 08-03-2007 21:09 » 

Кстати закрывать то главное окно и не желательно. При закрытии ты убьеш все приложение. Можно сделать недействительными (invisible) кнопки. Тогда главное окно будет как бы блокировано. В своем окне, находяшимся в Dll, в обработчике WM_DESTROY посылать нотификацию в головное окно. Это как один из вариантов. Кстати я так подумал. У тебя есть  еше два глюка:
1. Если повторно вызвать  ShowWnd() То старое окно как бы провисает. Оно сушествует и функцинирует, но для твоей программы потерено. Так называемая течь ресурсов.
2. FreeLibrary лучше убери с обработчика WM_DESTROY основного модуля. Так как ты выгружаеш библиотеку. Но окна еше не закрыты. Тут я точно не могу предсказать. Как будет вести себя винда. По идее говоря она должна выгрузить также и все ресурсы, связанные с библиотекой. Но может быть вывален Exception.

Насчет кнопок в DLL я подумаю завтра.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
sxd
Участник

ru
Offline Offline

« Ответ #17 : 09-03-2007 16:56 » 

Finch огромное спасибо за ценные советы!
Вот только кнопки...
Записан
sxd
Участник

ru
Offline Offline

« Ответ #18 : 11-03-2007 19:17 » 

Mr Finch так всё-таки как обработать нажатия кнопок в окне вызванном из DLL....
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines