Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Окна WinAPI, окна, окна, много окон... 
V
    Опции темы
N_Ghost
Дата 12.8.2008, 20:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 18.6.2008

Репутация: нет
Всего: нет



Есть окно на API. На окне есть кнопка, как при нажатии на эту кнопку открыть ещё одно окно допустим с настройками, и работать с ним как с основным обрабатывая все события? 
Пробовал дублировать классы и обработчик, появляется окно, но при закрытии закрывает всё. Видимо обработка WM_DESTROY идёт в основное окно тоже. Можно конечно отправить SW_HIDE, но тогда получается что оно висит в памяти?
Пробовал создавать второе окно в DLL, но это не выход. При закрытии закрывается и окно программы.
А вот если добавить второе окно из ресурсов, то происходит как раз то что и требуется.
Главная форма блокируется пока идёт работа с окном из RC, и при уничтожении окна возвращает доступ.
Как можно реализовать такое без использования ресурсов?
Если не сложно накидайте примерчик. Вроде ничего глобального нет.


Это сообщение отредактировал(а) N_Ghost - 12.8.2008, 21:46
PM MAIL   Вверх
Coder
Дата 13.8.2008, 01:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 733
Регистрация: 13.12.2004

Репутация: 1
Всего: 11



Цитата(N_Ghost @  13.8.2008,  04:41 Найти цитируемый пост)
А вот если добавить второе окно из ресурсов, то происходит как раз то что и требуется.Главная форма блокируется пока идёт работа с окном из RC, и при уничтожении окна возвращает доступ.

Если дело только в блокировке окна, то ее можно избежать.

В начале работы программы получаем Handler окна:
Код

  hGPSPanel:=CreateDialog(hInstan,MAKEINTRESOURCE(DLG_GPS_PANEL),hMainForm,@_GPSPanelProc);
  ShowWindow(hGPSPanel,SW_HIDE);


Открываем по  необходимости:
Код

ShowWindow(hGPSPanel,SW_SHOW);

PM MAIL   Вверх
N_Ghost
Дата 13.8.2008, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 18.6.2008

Репутация: нет
Всего: нет



нет, дело в том что мне как раз и надо блокировать главное окно пока идёт работа с вторым окном. но это не проблемма.
проблемма в том, как вызвать второе окно из одного модуля.
не совсем корректно объяснил, попробую на примере.

Код

......
// Первый класс
  with MainClass do
......
  lpfnWndProc:=@MainProc;
......
// Второй класс
// Надо ли его создавать если один уже зарегестрирован? 
// Но тогда как передать lpfnWndProc:=@PopupProc ?
with PopupClass do
......
  lpfnWndProc:=@PopupProc;
......
// Открываем второе окно при нажатии на кнопку
function MainProc ......
    WM_COMMAND:
......
WndPop := CreateWindowEx( 0, PopClass, PopCaption, WS_SYSMENU or WS_CAPTION  , 10, 10, 300, 300, 0, 0,  Instance, nil );
......
function PopupProc ......
// Что то делаем во втором окне
    WM_DESTROY: // Закрываем
    begin
      PostQuitMessage(0); // Закрываются все окна вместе с основным
    end;

пробовал через PostMessage с передачей нужного hWnd, закрывается всё.
склоняюсь к тому что у меня паталогически не правильный код, или на WM_DESTROY надо вешать что то типа ShowWindow(hWnd, SW_HIDE); 
 
PM MAIL   Вверх
N_Ghost
Дата 13.8.2008, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 18.6.2008

Репутация: нет
Всего: нет



в принципе всё решилось просто, это уже я начал изобретать велосипед smile

Код

program TestWind;
uses Windows, Messages;

const
WndMain = 'MainForm';
WndOpt = 'OptForm';
WndMainCap = 'Wind 1';
WndOptCap = 'Wind 2';
BTN1 = 10;
BTN2 = 11;
var
WMain, WOpt: TWndClassEx;
WndM, WndO: HWND;
Button: array[0..1] of HWND;
Msg: TMsg;
// Основное окно
function WndMainProc( Wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM ): LRESULT; stdcall;
  begin
   case Msg of
// Создаём второе окно
WM_COMMAND:
      case LOWORD(wParam) of
       BTN1:
        begin
        WndO := CreateWindowEx( 0, WndOpt, WndOptCap, WS_SYSMENU or WS_SIZEBOX or WS_CAPTION  ,
                          30, 30, 100, 100, 0, 0, hInstance, nil );
        Button[1] := CreateWindowEx( WS_EX_WINDOWEDGE, 'Button', 'Close', WS_VISIBLE or WS_CHILD,
                              10, 15, 70, 25, WndO, BTN2, hInstance, nil );
        ShowWindow( WndO, SW_SHOWNORMAL );
        end;
      end;
// Скидываем фокус если открыто второе окно
// Легкая блокировка
WM_WINDOWPOSCHANGED:
   begin
      if IsWindowVisible(WndO) then
         SetForegroundWindow(FindWindow(WndOpt, nil))
         else
         SetForegroundWindow(FindWindow(WndMain, nil));
   end;

WM_DESTROY:
      begin
         PostQuitMessage( 0 );
         Exit;
      end;
      else
         Result := DefWindowProc( Wnd, Msg, wParam, lParam );
  end;
end;
// Доп.окно
function WndOptProc( Wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM ): LRESULT; stdcall;
  begin
   case Msg of
      WM_COMMAND:
      case LOWORD(wParam) of
       BTN2:
        begin
         ShowWindow(WndO, SW_HIDE);
        end;
      end;

      WM_DESTROY:
      begin
     ShowWindow(WndO, SW_HIDE);
      end;
      else
         Result := DefWindowProc( Wnd, Msg, wParam, lParam );
  end;
end;

begin
// Первое
with WMain do
   begin
      cbSize := SizeOf( WMain );
      style := CS_HREDRAW or CS_VREDRAW;
      lpfnWndProc := @WndMainProc;
      cbClsExtra := 0;
      cbWndExtra := 0;
      hInstance := hInstance;
      hIcon := 0;
      hCursor := LoadCursor( 0, IDC_ARROW );
      hbrBackground := COLOR_WINDOW;
      lpszMenuName := nil;
      lpszClassName := WndMain;
   end;
RegisterClassEx( WMain );
WndM := CreateWindowEx( 0, WndMain, WndMainCap, WS_SYSMENU or WS_SIZEBOX or WS_CAPTION or WS_POPUP ,
                          10, 10, 300, 300, 0, 0, hInstance, nil );

Button[0] := CreateWindowEx( WS_EX_WINDOWEDGE, 'Button', 'Form 2', WS_VISIBLE or WS_CHILD,
                              10, 15, 60, 25, WndM, BTN1, hInstance, nil );

ShowWindow( WndM, SW_SHOWNORMAL );
// Второе
with WOpt do
   begin
      cbSize := SizeOf( WOpt );
      style := CS_HREDRAW or CS_VREDRAW;
      lpfnWndProc := @WndOptProc;
      cbClsExtra := 0;
      cbWndExtra := 0;
      hInstance := hInstance;
      hIcon := 0;
      hCursor := LoadCursor( 0, IDC_ARROW );
      hbrBackground := COLOR_WINDOW;
      lpszMenuName := nil;
      lpszClassName := WndOpt;
   end;
RegisterClassEx( WOpt );

while GetMessage( Msg, 0, 0, 0 ) do
  begin
   TranslateMessage( Msg );
   DispatchMessage( Msg );
  end;
end.


хотелось бы услышать комментарии на правильность всего этого.
PM MAIL   Вверх
volvo877
Дата 13.8.2008, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2073
Регистрация: 15.11.2004

Репутация: 5
Всего: 116



N_Ghost, ты ж не хотел, чтобы окно просто скрывалось, хотел уничтожать...

Код

function WndOptProc( Wnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM ): LRESULT; stdcall;
begin
  case Msg of
    WM_COMMAND:
      case LOWORD(wParam) of
        BTN2:
          begin
             SendMessage(WndO, WM_CLOSE, 0, 0);
          end;
      end;
    WM_DESTROY:
      begin
        DestroyWindow(WndO); // <--- Вот так, например
      end;
  else
    Result := DefWindowProc( Wnd, Msg, wParam, lParam );
  end;
end;
По-моему, должно работать...
PM MAIL   Вверх
N_Ghost
Дата 13.8.2008, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 18.6.2008

Репутация: нет
Всего: нет



volvo877, спасибо, работает! 
как то я проскочил в MSDN такую фунцию.
но самое смешное что при регистрации второго класса окна занимаемая память не меняется. скажем было 300Kb под приложение, 300 и остаётся. даже если удалить дополнительный класс.
нет, я просто хотел научится работать с окнами на чистом апи, без ресурсов.
есть куча примеров как создать окно, но нет не одного как создать два окна smile
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0732 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.