Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2015.03.01;
Скачать: [xml.tar.bz2];

Вниз

Окно на WinApi внутри Dll   Найти похожие ветки 

 
DagOT-R ©   (2010-04-13 11:31) [0]

Я пишу проект на WinAPI и GDI, и допустим, хочу написать Dll, из которой экспортирую функцию, которая вызывает контекстное меню. Однако, само меню я решил также написать как окно на WinAPI, т.к. для этого меню у меня есть собственный дизайн, с нарисованным фоном и кнопками. Внутри функции в Dll"ке я создаю и регистрирую класс окна, создаю собственно окно меню, там же находится процедура-обработчик сообщений окна. Однако, если после создания окна прописать цикл обработки сообщений TranslateMessage-DispatchMessage, то само собой, сама процедура создания контекстного меню "повесит" все приложение, пока меню не будет уничтожено. Собственно, вопрос в том, как в одном приложении использовать и обрабатывать несколько окон на WinAPI?


 
Дмитрий С ©   (2010-04-13 12:26) [1]

У тебя этот цикл в основной программе уже есть, он один для всех окон потока. Отдельный цикл нужно создавать для отдельного потока. Для каждого окна создавать отдельный цикл не нужно.

P.S. если не сложно скинь пример менюшки на winapi мне на почту reg argi ru.


 
Сергей М. ©   (2010-04-13 13:00) [2]


> если после создания окна прописать цикл обработки сообщений
> TranslateMessage-DispatchMessage, то само собой, сама процедура
> создания контекстного меню "повесит" все приложение, пока
> меню не будет уничтожено


Это с какого же перепугу "повесит" ?


 
DagOT-R ©   (2010-04-13 13:26) [3]

Собственно проблема в том, что при вызове меню ничего не происходит: функция вызывается корректно, но никаких следов появления меню, даже малейшей задержки в работе программы при загрузке изображений не происходит. Само меню пока очень сырое, и написано до момента, когда его можно подключить к проекту и тестировать. В нем не до конца прописано уничтожение окна и не прописана реакция на кнопки. Собственно, задумка такова:
Из Dll экспортируется ф-я ,которой передается хендл окна его вызывающего, передается адрес процедуры обратного вызова, которая будет обрабатывать события на кнопках из основного кода проекта, также передаются координаты курсора. Код оочень сырой, но выложу тут чтобы узнать, где именно кроется загвоздка.

library Menu;

uses
 Windows,
 SysUtils,
 Classes,
 messages;

type
  TRe_Action = (A_Exit, A_Hide, A_Show, A_SoundOn, A_SoundOff);
  TRe_Menu_proc = procedure (Action: TRe_Action; Param: Integer);
  PRe_Menu_proc = ^TRe_Menu_proc;

  Var
    Message: TMsg;

{$R Pics.res}
{$R *.res}

function ScreenWidth: integer;
begin
result:=GetSystemMetrics(SM_CXVIRTUALSCREEN);
end;

function ScreenHeight: integer;
begin
result:=GetSystemMetrics(SM_CYVIRTUALSCREEN);
end;

function Create_Menu(Handle: HWND; Menu_proc: PRe_Menu_proc; X, Y: integer): HWND; stdcall;
var
 wc : TWndClassEx;  //Переменная шаблона класса окна
 xPos,yPos,nWidth,nHeight : Integer;
 TRgn, FoneRgn: HRGN;
 Dc,hMemDc: Hdc;

 PIC_Exit1, PIC_Exit2, PIC_Exit3, PIC_Fone, PIC_Hide1, PIC_Hide2, PIC_Hide3,
 PIC_Show1, PIC_Show2, PIC_Show3, PIC_Soff1, PIC_Soff2, PIC_Soff3, PIC_Son1,
 PIC_Son2, PIC_Son3: HBitmap;

function BitmapToRgn(PosX, PosY, width, height: integer; Image: HBitmap): HRGN;
var
TmpRgn: HRGN;
x, y: Byte;
ConsecutivePixels: integer;
CurrentPixel: COLORREF;
CurrentColor: COLORREF;
 TmpDC: HDC;
begin
Result := CreateRectRgn(0, 0, PosX+width-1, PosY+height-1);
 TmpDC:= CreateCompatibleDC(Dc);
 SelectObject(TmpDC,Image);
for y := 0 to height-1 - 1 do
 begin
  CurrentColor := GetPixel(TmpDC,0,y);
  ConsecutivePixels := 1;
  for x := 0 to width-1 - 1 do
   begin
    CurrentPixel := GetPixel(TmpDC,x,y);
    if CurrentColor = CurrentPixel then
     inc(ConsecutivePixels)
    else
     begin // Входим в новую зону
      if (CurrentColor = $ff00ff) or (CurrentColor = $00C8C4C8) then
       begin
        TmpRgn := CreateRectRgn(PosX+x-ConsecutivePixels, PosY+y, PosX+x, PosY+y+1);
        CombineRgn(Result, Result, TmpRgn, RGN_DIFF);
        DeleteObject(TmpRgn);
       end;
      CurrentColor := CurrentPixel;
      ConsecutivePixels := 1;
     end;
   end;
  if ((CurrentColor = $ff00ff) or (CurrentColor = $00C8C4C8)) and (ConsecutivePixels > 0) then
   begin
    TmpRgn := CreateRectRgn(PosX+x-ConsecutivePixels, PosY+y, PosX+x, PosY+y+1);
    CombineRgn(Result, Result, TmpRgn, RGN_DIFF);
    DeleteObject(TmpRgn);
   end;
 end;
   DeleteDC(TmpDC);
end;

function WindowProc(wnd:HWND; Msg : Integer; Wparam:Wparam; Lparam:Lparam):Lresult; stdcall;
Begin
 {Далее происходит цикл обработки сообщений}
 case msg of
 wm_create :
   Begin
   DC := GetWindowDC(wnd);
    PIC_Exit1 := LoadBitmap(hInstance, "RE_M_EXIT1");
    PIC_Exit2 := LoadBitmap(hInstance, "RE_M_EXIT2");
    PIC_Exit3 := LoadBitmap(hInstance, "RE_M_EXIT3");
    PIC_Fone  := LoadBitmap(hInstance, "RE_M_FONE");
    PIC_Hide1 := LoadBitmap(hInstance, "RE_M_HIDE1");
    PIC_Hide2 := LoadBitmap(hInstance, "RE_M_HIDE2");
    PIC_Hide3 := LoadBitmap(hInstance, "RE_M_HIDE3");
    PIC_Show1 := LoadBitmap(hInstance, "RE_M_SHOW1");
    PIC_Show2 := LoadBitmap(hInstance, "RE_M_SHOW2");
    PIC_Show3 := LoadBitmap(hInstance, "RE_M_SHOW3");
    PIC_Soff1 := LoadBitmap(hInstance, "RE_M_SOFF1");
    PIC_Soff2 := LoadBitmap(hInstance, "RE_M_SOFF2");
    PIC_Soff3 := LoadBitmap(hInstance, "RE_M_SOFF3");
    PIC_Son1  := LoadBitmap(hInstance, "RE_M_SON1");
    PIC_Son2  := LoadBitmap(hInstance, "RE_M_SON2");
    PIC_Son3  := LoadBitmap(hInstance, "RE_M_SON3");
    FoneRgn := BitmapToRgn(0, 0, 129, 97, PIC_Fone);
    TRgn:= CreateRectRgn(0,0,1,1);
     CombineRgn(TRgn,FoneRgn,Trgn,RGN_COPY);
     SetWindowRgn(Wnd,Trgn,True);
    WindowProc:= DefWindowProc (wnd, Msg, WParam, LParam);
   End;
 wm_paint :
   Begin
    hMemDc := CreateCompatibleDC(dc);
    SelectObject(hMemDC,PIC_Fone);
    BitBlt(dc, 0, 0, 129, 97, hMemDC, 0, 0, SRCCOPY);
    DeleteDC(hMemDC);

    WindowProc:= DefWindowProc (wnd, Msg, WParam, LParam);
   End;
 wm_destroy :  //Сообщение посылаемое при уничтожении окна
   Begin
   ReleaseDC(Wnd, Dc);

    Result:=0;
         postquitmessage(0); exit;
    WindowProc:= DefWindowProc (wnd, Msg, WParam, LParam);
   End
  else Result:=DefWindowProc(wnd,msg,wparam,lparam);
 end;
End;
begin
result:=0;

wc.cbSize:=sizeof(wc);
wc.style:=cs_hredraw or cs_vredraw;
wc.lpfnWndProc:=@WindowProc;
wc.cbClsExtra:=0;

wc.cbWndExtra:=0;
wc.hInstance:=HInstance;
wc.hIcon:=LoadIcon(0,idi_application);
wc.hCursor:=LoadCursor(0,idc_arrow);
wc.hbrBackground:=COLOR_BTNFACE+1;
wc.lpszMenuName:=nil;
wc.lpszClassName:="TRE_Menu";
RegisterClassEx(wc); //Регистрация нового класса в системе

{"заполнение переменных xPos,yPos,nWidth,nHeight}
nWidth:=129;
nHeight:=97;

if ScreenWidth-X>=nWidth then
xPos:=x else xPos:=x-nWidth;
if ScreenHeight-Y>=nHeight then
yPos:=y else yPos:=y-nHeight;

{ Создание главного окна}
result:=CreateWindowEx (
0,                    //флаги расширенных стилей
"TRE_Menu",    //имя класса окна, данное при заполнении структуры wc
"RE_Menu",          //заголовок окна
ws_overlappedwindow+WS_VISIBLE, //флаги стилей окна
{подробнdее о стилях см. после текста программы}
xPos,               //горизонтальная позиция окна
yPos,               //вертикальная позиция окна

nWidth,             //ширина окна
nHeight,            //высота окна
Handle,                  //описатель родительского окна (parent) или окна-владельца (owner)
0,                  //описатель меню окна (меню нет, нет и описателя)
Hinstance,          //описатель приложения
nil                 //address of window-creation data
);
ShowWindow(result, SW_SHOW); //Отображаем окно
UpdateWindow (Result);
end;

exports
Create_Menu index 1 name "Create_Menu";

begin

end.


 
han_malign   (2010-04-13 13:43) [4]

круто... WindowProc - локальная функция ссылающаяся на локальные переменные внешней функции...
1. Delphi7 не поддерживает замыканий...
2. Прежде чем сношать мозги(и себе, и занятым людям) с DLL - убедись что работает "линейный" код в монолитном проекте...


 
DagOT-R ©   (2010-04-13 17:03) [5]

Все переменные, необходимые для создания и работы окна прописаны внутри функции. Естественно, не описывать же мне все переменные как глобальные!


 
DagOT-R ©   (2010-04-13 17:05) [6]

Где ты увидел замыкания в коде? Выразись пояснее, а то из твоих абстрактно-непонятных, но якобы очевидных обьяснений ничего непонятно.


 
Игорь Шевченко ©   (2010-04-13 17:47) [7]

DagOT-R ©   (13.04.10 17:03) [5]

Тебе явно указали, что оконная процедура не может быть вложенной.
Что ты препираешься ?


 
DagOT-R ©   (2010-04-14 00:41) [8]

Ок, ясно, спасибо, попробую исправить.


 
DagOT-R ©   (2010-04-14 01:42) [9]

И правда, все работает и рисуется отлично. Еще раз спасибо за помощь.


 
Дмитрий С ©   (2010-04-14 04:45) [10]

А разве такое компилируется для локальной WindowProc:
wc.lpfnWndProc:=@WindowProc;
?


 
DagOT-R ©   (2010-04-14 14:14) [11]

Вот выложу готовый проект, в котором используется это меню, загружаемое через dll.
Оконная сиделка Мэй [3.04 Мб]:
http://ani-grafick.ucoz.ru/oursoft/May2.rar
Исходники и текстуры библиотеки [242 Кб]:
http://ani-grafick.ucoz.ru/oursoft/Menu.rar



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2015.03.01;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.002 c
4-1271143894
DagOT-R
2010-04-13 11:31
2015.03.01
Окно на WinApi внутри Dll


15-1405892115
Германн
2014-07-21 01:35
2015.03.01
Viber - что это такое?


15-1405873356
Timer
2014-07-20 20:22
2015.03.01
Об уличных вакуумных наушниках


2-1391083752
Alex_C
2014-01-30 16:09
2015.03.01
MainMenu не самое врхнее


15-1405801802
Юрий
2014-07-20 00:30
2015.03.01
С днем рождения ! 20 июля 2014 воскресенье





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский