![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как запустить окно (winapi) по клику кнопки? [D7, XP]
Сергей © (2011-01-18 16:55:00)Создал окно через WinApi
program Project1;
uses
Windows, Messages;
const
WndClass = 'TWinApiWnd';
WndCaption = '';
// Кнопки, на которые будет выведен текст
BTN_TEXT_0 = 6;
var
Wc: TWndClassEx;
Wnd: HWND;
Msg: TMsg;
Buttons: array[0..8] of HWND;
Icon: HICON;
Font: HFONT;
(* Оконная процедура *)
function WindowProc( Wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM ): LRESULT; stdcall;
begin
case Msg of
WM_DESTROY: begin
PostQuitMessage( 0 );
Result := 0;
Exit;
end;
// Обработка сообщений от кнопок
WM_COMMAND:
case LoWord( wParam ) of
BTN_TEXT_0: begin
MessageBox( Wnd, 'Button1', 'Кнопка:', MB_OK );
SetFocus( Buttons[6] );
end;
end;
else
Result := DefWindowProc( Wnd, Msg, wParam, lParam );
end;
end;
begin
// Заполняем структуру TWndClassEx
with Wc do
begin
cbSize := SizeOf( Wc );
style := CS_HREDRAW or CS_VREDRAW ;
lpfnWndProc := @WindowProc;
cbClsExtra := 0;
cbWndExtra := 0;
hInstance := hInstance;
hIcon := LoadIcon( 0, IDI_APPLICATION );
hCursor := LoadCursor( 0, IDC_ARROW );
hbrBackground := COLOR_WINDOW;
lpszMenuName := nil;
lpszClassName := WndClass;
end;
// Регистрируем класс в системе
RegisterClassEx( Wc );
// Создаем окно
Wnd := CreateWindowEx( WS_EX_PALETTEWINDOW, WndClass, WndCaption, WS_POPUP or WS_VISIBLE,
600, 500, 50, 50, 0, 0, hInstance, nil );
Buttons[6] := CreateWindowEx( WS_EX_STATICEDGE, 'Button', 'Button1', WS_VISIBLE or WS_CHILD,
0, 0, 30, 30, Wnd, BTN_TEXT_0, hInstance, nil );
Font := GetStockObject( ANSI_VAR_FONT );
SendMessage( Buttons[6], WM_SETFONT, Font, 0 );
// Показываем окно
ShowWindow( Wnd, SW_SHOWNORMAL );
// Цикл обработки сообщений
while GetMessage( Msg, 0, 0, 0 ) do
begin
TranslateMessage( Msg );
DispatchMessage( Msg );
end;
Halt( Msg.wParam );
end.
проект компилируется и окно создается.
Как теперь этот проект привязать к главному проекту что бы
создавать это окно по клику на кнопке в форме главного проекта?
Servy (2011-01-19 02:58:00) [1]
> > про WinExec внимательно help почитай.
>
>
> А что с ним? Просто не понятно что именно нужно сделать.
> ..
Note This function is provided only for compatibility with 16-bit Windows. Applications should use the CreateProcess function.
> Как компилятор отличит что чему мы хотим присвоить-то?
Эээ. Компилятор не дурак, чтобы отгадывать кто там что хотел, когда код писал. Он строго по регламенту и документации работает. Если есть hInstance в структуре, которую мы with - значит используем его. Если нету - ищем в более широкой области видимости. Засим, сия строчка делает ровным счетом ничего полезного.
Чтобы явно объяснить, чего мы хотим, можно написать:
hInstance := SysInit.HInstance;
> Я всегда делал hInst:=GetModuleHandle(Nil); Wc.hInstance:
> =hInst;
hInstance итак при инициализации приложения кладется в одноименную глобальную переменную. Впрочем, вызвать GetModuleHandle тоже ничего не мешает.
Студент (2011-01-19 00:41:00) [2]
> про WinExec внимательно help почитай.
А что с ним? Просто не понятно что именно нужно сделать...
> А в чём проблема?
> var
А там ж оно вwith Wc doполучалось... Поле структуры и глобальная переменная с одинаковыми идентификаторами... Как компилятор отличит что чему мы хотим присвоить-то?
Я всегда делалhInst:=GetModuleHandle(Nil); Wc.hInstance:=hInst;
Ega23 (2011-01-19 00:28:00) [3]
> запускать через WinExec
про WinExec внимательно help почитай.
> А как компилятор понимал hInstance:=hInstance; ?
А в чём проблема?
var
a: Integer;
begin
a := a;
Германн (2011-01-18 23:45:00) [4]
> А как компилятор понимал hInstance:=hInstance;
В тот-то вся шутка :)
Студент (2011-01-18 23:37:00) [5]
> проект компилируется и окно создается.
> Как теперь этот проект привязать к главному проекту что
> бы создавать это окно по клику на кнопке в форме главного проекта?
Поясните что именно нужно-то? Может при нажатии кнопки просто запускать через WinExec уже скомпилированный exe?
> Стандартная ошибка
Нужно ж кажетсяGetModuleHandle(Nil), да?) Лучше ли завести глобальную переменную и сделать вызов GetModuleHandle один раз или можно при каждом нужном случае его снова вызывать всякий раз?
А как компилятор понималhInstance:=hInstance;?
Юрий Зотов (2011-01-18 18:30:00) [6]Стандартная ошибка:
with Wc do
...
hInstance := hInstance;
Юрий Зотов (2011-01-18 18:22:00) [7]
> Юрий Зотов © (18.01.11 18:07) [2]
> это окно Вы создаете в главном потоке VCL
Сейчас придет двоичный программист (скорее всего, я даже знаю, кто именно) и грозно спросит: "Где в приведенном коде [0] Вы нашли главный поток VCL и его цикл выборки сообщений?"
Иногда все же вспоминается фильм "Сережа"...
:o)
Юрий Зотов (2011-01-18 18:10:00) [8]Пример окна, написанного без VCL и работающего в собственном потоке:
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1411
Юрий Зотов (2011-01-18 18:07:00) [9]Есть другой вариант - создать невидимое окно, а по клику только его показывать. Иначе при каждом клике будем получать новое окно.
Но есть и вопрос - это окно Вы создаете в главном потоке VCL, который имеет свой собственный цикл выборки сообщений. Как этот цикл будет сочетаться с Вашим циклом?
Видимо, это окно должно работать в своем собственном потоке.
KSergey (2011-01-18 17:08:00) [10]Все что от begin по вот эти строчки (включительно)
// Регистрируем класс в системе
RegisterClassEx( Wc );
пихаем в метод Create главной формы проекта.
Начиная от "// Создаем окно" и до
// Показываем окно
ShowWindow( Wnd, SW_SHOWNORMAL );
включительно пихаем в обработчик клика по кнопке.
Начиная с // Цикл обработки сообщений и ниже - выкидываем.
Понятно, что WindowProc и константы должно где-то присутсвовать в файлах проекта