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

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

Как запустить окно (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 и константы должно где-то присутсвовать в файлах проекта


Наверх

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