Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Криво работает окно в dll при вызове из VCL exe [D7, WinXP]


Страницы:   1 2 3

parovoZZ ©   (2006-05-13 13:50:00) 

В ресурсах dll создал окно (в секции DIALOG), но при вызове оттуда работает криво: не двигается за шапку, все элементы съехали вниз, при потере фокуса обратно он не возвращается, хотя кнопки нажимаются, текст вводится. Может там надо создать своё родительское окно, а не передавать в качестве родителя хендл главной формы exe?

function LoginProc (DlgHandle: THandle; Msg, wParam, lParam: Integer) : integer; stdcall; export;
begin
case Msg of

  WM_COMMAND :
   case wParam of

    OK_Button :                          
      begin                      
       SendMessage (Handle, WM_LOGIN, WM_OK, 0);
       DestroyWindow (DlgHandle);
      end;

    Cancel_Button :
      begin
       DestroyWindow (Handle);
      end;
   end;

  WM_SYSCOMMAND :
   case wParam of

    SC_Close :
     begin
      DestroyWindow (Handle);
     end;
   end;

end;
Result := DefWindowProc (DlgHandle, Msg, wParam, lParam);
end;


parovoZZ   (2006-05-29 20:26:00) [1]

 repeat
  DataModule.Destroy;
  if not DMd.Login (MainHandle) then
   begin
    Application.Run;
    exit;
   end;
 until DMd.Authorization = true;


Всё заработало. Век живи, век учись. VCL, чтоб его.


parovoZZ   (2006-05-28 23:38:00) [2]

Ну вообщем отказался от сообщений из dll. Сделал так:
library OJDialog;

uses
 Messages,
 Windows;

const
OK_Button = 101;
Cancel_Button = 102;
Login_Edit = 103;
Password_Edit = 104;

var
MainHandle,
 DlgHandle, _DlgHandle   : THandle;
_result      : byte;
edLogin, edPassword : ShortString;

{$R Login.Res}

procedure GetInfo (Handle : THandle);
var
Text : array [0..20] of Char;

begin
GetDlgItemText (Handle, Login_Edit, Text, 20);
edLogin := Text;
GetDlgItemText (Handle, Password_Edit, Text, 20);
edPassword := Text;
end;

procedure Centering (Handle : THandle);
var
Rect              : TRect;
iWidth, iHeight   : word;

begin
GetWindowRect (Handle, Rect);
iWidth := Rect.right - Rect.left;
iHeight := Rect.bottom - Rect.top; //öåíòðîâêà äèàëîãà
Rect.left := (GetSystemMetrics (SM_CXSCREEN) - iWidth) Div 2;
Rect.top := (GetSystemMetrics (SM_CYSCREEN) - iHeight) Div 2;
MoveWindow (Handle, Rect.left, Rect.top, iWidth, iHeight, False);
SetForegroundWindow (Handle);
end;

function ConnectShowProc (DlgHandle: THandle; Msg, wParam, lParam: Integer) : boolean; stdcall;
begin
result := WordBool (0);

case Msg of

  WM_ShowWindow  : begin
                    Centering (DlgHandle);
                   end;

    WM_Destroy   : begin
                    //EndDialog (DlgHandle, DlgHandle);
                    //DlgHandle := 0;
                    Exit;
                   end;
end;
end;

procedure ConnectShow; stdcall
begin
DlgHandle := CreateDialog (hInstance, 'ConnectShow', MainHandle, @ConnectShowProc);
end;

function LoginProc (DlgHandle: THandle; Msg, wParam, lParam: Integer) : boolean; stdcall;
begin
result := WordBool (0);
case Msg of

  WM_COMMAND :
   case wParam of

    OK_Button :
      begin
       GetInfo (DlgHandle);
       DestroyWindow (DlgHandle);
       _result := IDOK;
      end;

    Cancel_Button :                              
      begin                                        
       DestroyWindow (DlgHandle);
       _result := IDCANCEL;
      end;
   end;

  WM_SYSCOMMAND :
   case wParam of

    SC_Close :
     begin
      DestroyWindow (DlgHandle);
      _result := IDCLOSE;
   
     end;
   end;

  WM_ShowWindow : begin
                   Centering (DlgHandle);
                  end;

  WM_Destroy    : begin
                   EndDialog (DlgHandle, _DlgHandle);
                   _DlgHandle := 0;
                   Exit;
                  end;

end;
end;

procedure Execute (aMainHandle : THandle); stdcall;
begin
MainHandle := aMainHandle;
end;

function Login : byte; stdcall;
begin
_DlgHandle := DialogBox (hInstance, 'LOGIN', MainHandle, @LoginProc);
//_DlgHandle := CreateDialog (hInstance, 'LOGIN', MainHandle, @LoginProc);
result := _result;

end;

procedure PostInfo (var aLogin, aPassword : ShortString); stdcall;
begin
aLogin := edLogin;
aPassword := edPassword;
end;

procedure Destroy; stdcall;
begin
DestroyWindow (DlgHandle);
end;

Exports
Execute name 'Execute',
Login name 'Login',
PostInfo name 'PostInfo',
ConnectShow name 'ConnectShow',
Destroy name 'Destroy';

end.


Вызываем примерно так:

Application.Initialize;
 Application.Title := 'Operative Journal';
 Application.CreateForm (TDMd, DMd);
 MainHandle := Application.Handle;
 LoadDll (MainHandle);
 repeat
  DataModule.Destroy;
  if not DMd.Login (MainHandle) then exit;
 until DMd.Authorization = true;

 Application.CreateForm (TMainForm, MainForm);
 DataModule.Destroy;
 UnloadDll;
 Application.Run;


При первом нажатии Cancel в окне авторизации (окно создаётся в теле функции Login) приложение завершает работу и выпадает Access Violatin (из-за чего?). Если нажать ОК не вводя при этом логина, то показывается окно хода подключения (вызов функции ConnectShow), после чего из отдельной dll выскакивает мессага об ошибке подключения. Далее, подтверждаем мессагу об ошибке и снова появляется окно авторизации. А вот если теперь нажать на Cancel, то приложение завершается без вопросов. Почему так?


Leonid Troyanovsky   (2006-05-23 18:57:00) [3]


> parovoZZ ©   (23.05.06 09:22) [39]

> Ну ладно, обсуждение плавно перешло в перебранку.


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

Если, конечно, мыслительные мышцы атрофированы, то я - пас.

Т.е., пожалуйте-с, по существу, бо домысливать что-либо
в конце рабочего дня мне влом.

--
Regards, LVT.


Polevi   (2006-05-23 09:43:00) [4]

нефиг сук пилить на котором сидишь


parovoZZ   (2006-05-23 09:22:00) [5]

А где ей ещё быть?
Ну ладно, обсуждение плавно перешло в перебранку.


Leonid Troyanovsky   (2006-05-23 06:57:00) [6]


> parovoZZ ©   (23.05.06 00:26) [37]

> Ловлю мессагу о нажатии кнопки в окне из dll и выгружаю
> библиотеку без предупреждения. А в оконном обработчике по
> этому событию окно не убивается.
> WM_Cancel : FreeLibrary (HandleDll)


Сильно. Это притом, что оконная процедура в библиотеке.
Конечно же, буратино.

--
Regards, LVT.


parovoZZ   (2006-05-23 00:26:00) [7]

Сильно :)

Очень просто
Ловлю мессагу о нажатии кнопки в окне из dll и выгружаю библиотеку без предупреждения. А в оконном обработчике по этому событию окно не убивается.
WM_Cancel : FreeLibrary (HandleDll)

Что будет с памятью?

На самом деле окно будет не модальным, потому как сперва будет появляться окошко авторизации, а уже потом всё остальное. Сейчас буду ныть в соседнем топике, как это реализовать в dll.))


Leonid Troyanovsky   (2006-05-22 21:35:00) [8]


> parovoZZ ©   (22.05.06 20:11) [35]

> Ну?


Гну.

> Так как убить окно в dll при выгрузке библиотеки?

Вот, скажи, и как это при  модально показанном окне
будет происходить выгрузка библиотеки?

Нет, конечно, представить и такое можно, но,
в этом случае, ты сам себе злобный буратино.

--
Regards, LVT.


parovoZZ   (2006-05-22 20:11:00) [9]

Ну?

Так как убить окно в dll при выгрузке библиотеки?

Так, а при статической загрузке dll при её выгрузке (завершении работы приложения) само всё отвалится или тоже надо явно освобождать?


Leonid Troyanovsky   (2006-05-22 18:49:00) [10]


> parovoZZ ©   (22.05.06 00:39) [33]

> Ну получается, что о выгрузке библиотеки я узнаю только
> через Dll_Process_Detach. ОКНО в DLL у меня уже создано.


И?
Окна, вообще-то, собственность потока.
Место их создания на высоту полетов не влияет.

--
Regards, LVT.


parovoZZ   (2006-05-22 00:39:00) [11]

Ну получается, что о выгрузке библиотеки я узнаю только через Dll_Process_Detach. ОКНО в DLL у меня уже создано.


Leonid Troyanovsky   (2006-05-21 17:53:00) [12]


> parovoZZ ©   (20.05.06 15:43) [31]

> Ну при выгрузке библиотеки надо вызывать EndDialog или нет?


Вызывай.
А при чем тут сабж?

--
Regards, LVT.


parovoZZ   (2006-05-20 15:43:00) [13]

Ну при выгрузке библиотеки надо вызывать EndDialog или нет?


Leonid Troyanovsky   (2006-05-19 18:44:00) [14]


> parovoZZ ©   (19.05.06 18:38) [29]

> FreeLibrary порождает сообщение WM_DESTROY для DLL?


Нет, ясен пень.

> Или надо отлавливать Dll_Process_Detach?


Почему "или"? В чем связь?
Извольте изъясняться доступней.

--
Regards, LVT.


parovoZZ   (2006-05-19 18:38:00) [15]

А ещё вопрос

FreeLibrary порождает сообщение WM_DESTROY для DLL? Или надо отлавливать Dll_Process_Detach?


Игорь Шевченко   (2006-05-19 09:27:00) [16]


> Кто прав?


Оба.


parovoZZ   (2006-05-18 21:17:00) [17]

А мне тут подсказали, что надо регистрировать доморощенные сообщения в системе, если работаешь с VCL
RegisterWindowMessage ('WM_Login');

А вот видел исходник на апях, так там просто
Const
WM_LOGIN = WM_APP + цЫфра.

Кто прав?

//Причём на VCL по последнему методу путаются wParam и lParam.


parovoZZ   (2006-05-15 22:10:00) [18]

МОЖНО ВСЁ!!!

Заменил String на ShortString и всё запахало.

А вот как по-другому перехватить нажатие кнопки в dll и отправить данные в exe? Как-то навароченно получилось.


parovoZZ   (2006-05-15 20:56:00) [19]

Всё, с хeндлом разобрался. Там надо было явно передавать его из оконной процедуры. Но есть другая ерунда:
case msg.wParam of

 WM_OK     : begin
              @PostInfo := GetProcAddress (HandleDll, 'PostInfo');
              if @PostInfo <> nil then PostInfo (edLogin, edPassword);
              FreeLibrary (HandleDll);
              login := edLogin;     <<-Access Violatin
              User := edPassword;
//
             end;

В DLL :


procedure GetInfo (Handle : THandle);
var
Text : array [0..20] of Char;

begin
GetDlgItemText (Handle, Login_Edit, Text, 20);
edLogin := Text;
GetDlgItemText (Handle, Password_Edit, Text, 20);
edPassword := Text;
end;

procedure PostInfo (var aLogin, aPassword : string); stdcall;
begin
aLogin := edLogin;
aPassword := edPassword;
end;


Нельзя что ли возвращать значение переменной из dll ?


parovoZZ   (2006-05-15 19:59:00) [20]

WM_Destroy : EndDialog (DlgHandle, {?}); -> WM_Destroy : EndDialog (DlgHandle, DlgHandle);???
Ни в какие ворота не лезет :)


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо