Форум: "Начинающим";
Текущий архив: 2011.04.24;
Скачать: [xml.tar.bz2];
ВнизКак запустить окно (winapi) по клику кнопки? Найти похожие ветки
← →
Сергей (2011-01-18 16:55) [0]Создал окно через 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.
проект компилируется и окно создается.
Как теперь этот проект привязать к главному проекту что бы
создавать это окно по клику на кнопке в форме главного проекта?
← →
KSergey © (2011-01-18 17:08) [1]Все что от begin по вот эти строчки (включительно)
// Регистрируем класс в системе
RegisterClassEx( Wc );
пихаем в метод Create главной формы проекта.
Начиная от "// Создаем окно" и до
// Показываем окно
ShowWindow( Wnd, SW_SHOWNORMAL );
включительно пихаем в обработчик клика по кнопке.
Начиная с // Цикл обработки сообщений и ниже - выкидываем.
Понятно, что WindowProc и константы должно где-то присутсвовать в файлах проекта
← →
Юрий Зотов © (2011-01-18 18:07) [2]Есть другой вариант - создать невидимое окно, а по клику только его показывать. Иначе при каждом клике будем получать новое окно.
Но есть и вопрос - это окно Вы создаете в главном потоке VCL, который имеет свой собственный цикл выборки сообщений. Как этот цикл будет сочетаться с Вашим циклом?
Видимо, это окно должно работать в своем собственном потоке.
← →
Юрий Зотов © (2011-01-18 18:10) [3]Пример окна, написанного без VCL и работающего в собственном потоке:
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1411
← →
Юрий Зотов © (2011-01-18 18:22) [4]
> Юрий Зотов © (18.01.11 18:07) [2]
> это окно Вы создаете в главном потоке VCL
Сейчас придет двоичный программист (скорее всего, я даже знаю, кто именно) и грозно спросит: "Где в приведенном коде [0] Вы нашли главный поток VCL и его цикл выборки сообщений?"
Иногда все же вспоминается фильм "Сережа"...
:o)
← →
Юрий Зотов © (2011-01-18 18:30) [5]Стандартная ошибка:
with Wc do
...
hInstance := hInstance;
← →
Студент (2011-01-18 23:37) [6]
> проект компилируется и окно создается.
> Как теперь этот проект привязать к главному проекту что
> бы создавать это окно по клику на кнопке в форме главного проекта?
Поясните что именно нужно-то? Может при нажатии кнопки просто запускать через WinExec уже скомпилированный exe?
> Стандартная ошибка
Нужно ж кажетсяGetModuleHandle(Nil)
, да?) Лучше ли завести глобальную переменную и сделать вызов GetModuleHandle один раз или можно при каждом нужном случае его снова вызывать всякий раз?
А как компилятор понималhInstance:=hInstance;
?
← →
Германн © (2011-01-18 23:45) [7]
> А как компилятор понимал hInstance:=hInstance;
В тот-то вся шутка :)
← →
Ega23 © (2011-01-19 00:28) [8]
> запускать через WinExec
про WinExec внимательно help почитай.
> А как компилятор понимал hInstance:=hInstance; ?
А в чём проблема?var
a: Integer;
begin
a := a;
← →
Студент (2011-01-19 00:41) [9]
> про WinExec внимательно help почитай.
А что с ним? Просто не понятно что именно нужно сделать...
> А в чём проблема?
> var
А там ж оно вwith Wc do
получалось... Поле структуры и глобальная переменная с одинаковыми идентификаторами... Как компилятор отличит что чему мы хотим присвоить-то?
Я всегда делалhInst:=GetModuleHandle(Nil); Wc.hInstance:=hInst;
← →
Servy © (2011-01-19 02:58) [10]
> > про 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 тоже ничего не мешает.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2011.04.24;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.004 c