Конференция "WinAPI" » Несколько окон WinAPI
 
  • Я__ (14.08.14 23:28) [0]
  • Rouse__ (15.08.14 00:00) [1]
    Ну... Если глубоко не вдаваться в подробности, то несколько раз вызвать CreateWindow()
  • Я__ (15.08.14 00:35) [2]
    А как же TWndClassEx? или только для главного окна? Где вызывать CreateWindowEX? и для чего ShowWindow?
  • Я__ (15.08.14 00:40) [3]
    В VCL взвать окно просто Form.Show. а winapi....????
  • junglecat (15.08.14 09:32) [4]
    > [2] Я__   (15.08.14 00:35)

    Класс окна регистрируется один раз.
    CreateWindowEX вызывается столько, сколько нужно экземпляров окон.
    ShowWindow с флагом SW_SHOW вызывается столько, сколько нужно видимых окон.
  • Я__ (15.08.14 18:41) [5]
    Приветствую всех. Переписываю с VCL на WinPI проект с 7 или 8 окнами. Основная офрма постоянно использует компоненты двух форм.
    Есть некие наработки:

    Function WinProc(Form: hwnd; // Окно-получатель каждого входящего сообщения
     Msg: Cardinal; // Само сообщение
    wparam: WParam; // Первый и второй уточняющие параметры сообщения
     LParam: Cardinal): lresult; Stdcall; // Оконная процедура, здесь мы задаем реакцию программы на все нужные нам сообщения
    Var
     Rect: TRect; // Для записи размеров клиентской области нашего окна
    Begin
     Result := 0; // Чтобы в случае сбоя программы до последней строки функции Windows правильно определила ошибку
     Case Msg Of
       WM_CREATE: // При создании окна:
       Begin

         //Создаём кнопку
       listbox := CreateWindowEx(0, 'listbox','',WS_CHILD Or WS_VISIBLE, 250, 0, Form, Form, Form, listboxid, HInstance,nil);
       label1 := CreateWindowEx(0, 'Static', '123',WS_CHILD Or WS_VISIBLE, 10  ,10, 100, 15, Form, label1ID, HInstance,nil);

       button :=  CreateWindowEx (0, 'BUTTON',  'Кнопка', WS_CHILD Or WS_VISIBLE Or BS_PUSHBUTTON,  0, 0, 100, 20, Form,  ButtonID, HInstance, NIL);

         SendMessage(GetDlgItem(Form, ButtonID), WM_SETFONT,  0, -1); // Меняем шрифт
       End;

       WM_COMMAND: // Через это сообщение определяем нажатие на кнопку
        //Если мессага пришла от кнопки
         If LoWord (WParam) = ButtonID Then
           //И если это было нажатие
           If HiWord (WParam) = BN_CLICKED then
             begin
                   If RegisterClassEx(WndClassEx) = 0 Then
                     MessageBox(0, 'Невозможно зарегистрировать класс окна', 'Ошибка', MB_OK Or MB_ICONHAND)
                   Else
                     Begin
                       HWnd1 :=   CreateWindowEx(0,'FindWindow', 'Дочернее', WS_OVERLAPPEDWINDOW, 10 ,70,200,130, Form, 0,HInstance, NIL);

                       SetParent(HWnd1, 0);
                       ShowWindow(HWnd1, SW_SHOW);

                         If HWnd1 = 0 Then // Если окно не создалось:
                           MessageBox (0, 'Окно не создалось!',
                             'Ошибка', MB_OK Or MB_ICONHAND)
                         Else
                           Begin
                             ShowWindow (HWnd1, SW_SHOWNORMAL); // Показывем окно
                             UpdateWindow(HWnd1); // Перерисовываем окно

                           End;  

                           While GetMessage(Msg1, 0, 0, 0) Do
                       Begin
                         TranslateMessage(Msg1);
                         DispatchMessage(Msg1);
                       End;      
             end;

       WM_DESTROY: // При уничтожении окна (можно и не задавать реакцию - прога автоматически выгрузится, однако оставив след в памяти)
         PostQuitMessage(0); // Помещает в очередь сообщений сообщение завершения работы программы (WM_QUIT)
       Else // Если пришедщее сообщение мы не определили:
         Result := DefWindowProc(Form, Msg, WParam, LParam); // Эта функция обрабатывает ВСЕ ОСТАЛЬНЫЕ сообщения по умолчанию
     End; // Конец блока Case
    End;

    procedure Ocno;
    //var
    // WndClassEx1: TWndClassEx; // Класс окна - несёт инфу об окне (запись)
    begin
     WndClassEx.cbSize := SizeOf(WndClassEx); // Размер структуры
               WndClassEx.lpszClassName := 'FindWindow'; // Имя класса окна (для примера - второй параметр функции FindWindow)
               WndClassEx.style := cs_hredraw or cs_vredraw; // Стили окна - в данном случае окно будет перерисовываться при изменении как горизонтальных, так и вертикальных размеров
               WndClassEx.hInstance := HInstance; // Ищи описание выше
               WndClassEx.lpfnWndProc := @childwindowproc;//@WinProc; // адрес окнной процедуры
               WndClassEx.cbClsExtra := 0;
               WndClassEx.cbWndExtra := 0;
               WndClassEx.hIcon := LoadIcon(HInstance, MakeIntResource('MAINICON')); // Икнока окна
               WndClassEx.hIconSm := LoadIcon(HInstance, MakeIntResource('MAINICON')); // Тоже иконка (но маленькая :)
               WndClassEx.hCursor := LoadCursor(0, IDC_ARROW); // Курсор мыши для окна (у нас - стрелка)
               WndClassEx.hbrBackground := COLOR_BTNFACE + 1; // Фон окна
               WndClassEx.lpszMenuName := NIL; // Указатель на меню (у нас ме
               registerclassex(WndClassEx);// регистрируем в системе новый класс окна
    end;

    Procedure WinMain; // Эта процедура сформирует окно и отобразит его, запустив цикл обработки сообщений
    Begin
     WndClassEx.cbSize := SizeOf(TWndClassEx);
     WndClassEx.lpszClassName := 'APIWindow'; // Имя класса окна (для примера - второй параметр функции FindWindow)
     WndClassEx.style := CS_VREDRAW Or CS_HREDRAW; // Стили окна - в данном случае окно будет перерисовываться при изменении как горизонтальных, так и вертикальных размеров
     WndClassEx.hInstance := HInstance; // Ищи описание выше
     WndClassEx.lpfnWndProc := @WinProc; // адрес окнной процедуры
     WndClassEx.cbClsExtra := 0;
     WndClassEx.cbWndExtra := 0;
     WndClassEx.hIcon := LoadIcon(HInstance, MakeIntResource('MAINICON')); // Икнока окна
     WndClassEx.hIconSm := LoadIcon(HInstance, MakeIntResource('MAINICON')); // Тоже иконка (но маленькая :)
     WndClassEx.hCursor := LoadCursor(0, IDC_ARROW); // Курсор мыши для окна (у нас - стрелка)
     WndClassEx.hbrBackground := COLOR_BTNFACE + 1; // Фон окна
     WndClassEx.lpszMenuName := NIL; // Указатель на меню (у нас меню нет)
     //registerclassex(WndClassEx);// регистрируем в системе новый класс окна

     // Теперь регистрируем класс окна в системе
     If RegisterClassEx(WndClassEx) = 0 Then
       MessageBox(0, 'Невозможно зарегистрировать класс окна', 'Ошибка', MB_OK Or MB_ICONHAND)
     Else
     Begin
     // Создаём окно
       Form := CreateWindowEx( WS_EX_OVERLAPPEDWINDOW,  WndClassEx.lpszClassName, 'Демонстрация WinAPI',
         WS_OVERLAPPEDWINDOW,
        1000,100, //CW_USEDEFAULT, 0,
         500, 500,  
         0, 0,
         HInstance,
         NIL);
         SendMessage(GetDlgItem(Form, ButtonID), WM_SETFONT,  0, -1);
       If Form = 0 Then
         MessageBox (0, 'Окно не создалось!',
           'Ошибка', MB_OK Or MB_ICONHAND)
       Else
       Begin
         ShowWindow (Form, SW_SHOWNORMAL);
         UpdateWindow(Form);

         While GetMessage(MMsg, 0, 0, 0) Do
         Begin
           TranslateMessage(MMsg);
           DispatchMessage(MMsg);
         End;
         Halt(MMsg.WParam);
       End;
     End;
    End;

    Begin
     Ocno;    WinMain;
    End.



    Допустим зарегистрировал класс для каждого окна. тогда где надо прописать создание (createWindow) окна? А showWindow - грубо говоря по нажатию кнопки.

    Если не тяжело и не затруднит, приведите рабочий пример с двумя окнами (Лучше больше).
    И еще, как правильно закрыть вызываемые окна?
  • Rouse_ © (15.08.14 18:53) [6]
    CreateWindowEx у тебя только один раз вызван, поэтому окно одно.
    Слушай может ты не много окон хочешь в режиме SDI, а устарелый режим MDI, но не можешь обьяснить толком?
  • Я__ (15.08.14 19:13) [7]
    как один раз вызван
    > Form := CreateWindowEx( WS_EX_OVERLAPPEDWINDOW,  WndClassEx.
    > lpszClassName, 'Демонстрация WinAPI',


    > HWnd1 :=   CreateWindowEx(0,'FindWindow', 'Дочернее', WS_OVERLAPPEDWINDOW,
    >  10 ,70,200,130, Form, 0,HInstance, NIL);


    Rouse_ © ----- Спасибо что помогаете, НО ХОТЕЛОСЬ БЫ  рабочий пример с двумя окнами (Лучше больше). Не обижайтесь. Спасибо!
  • Я__ (15.08.14 19:16) [8]

    > а устарелый режим MDI

    нет.
    нормальное окною
  • Rouse_ © (15.08.14 19:44) [9]

    > Rouse_ © ----- Спасибо что помогаете, НО ХОТЕЛОСЬ БЫ  рабочий
    > пример с двумя окнами (Лучше больше). Не обижайтесь. Спасибо!
    >

    Т.е. приложение на API в виде диалога с кнопкой, при нажатии на которую создаются новые немодальные окна устроит?
  • Я__ (15.08.14 19:49) [10]
    Да.
  • Я__ (15.08.14 19:51) [11]
    Мне хочется просто понять принцип создания и вызова немодальных окон из родительского
  • Rouse_ © (15.08.14 19:52) [12]
    Ок, после выходных накидаю примерчик :)
  • Я__ (15.08.14 19:53) [13]
    Rouse_ © Спасибо огромное.
  • Я__ (16.08.14 16:58) [14]
    А кто сожет ответить --- ListView(SysLstView32), содержит строки и если он не в фокусе, то выделение строки пропадает и появляестя когда в фокусе. как исправить?
    В Delphi (VCL) нужно было сделать --- ListView.HideSelection := False.
    А в WinAPI как? Спасибо.
  • junglecat (16.08.14 21:11) [15]
    стиль LVS_SHOWSELALWAYS
  • Я__ (16.08.14 22:51) [16]
    Как обработать Click и DblClick по ListView как и куда писать и как изенить цвет текста выделенной строки?
  • ухты (17.08.14 01:08) [17]
    далее будет вопрос про клавиатуру ...
  • Я__ (17.08.14 01:13) [18]

    > ухты  
    > далее будет вопрос про клавиатуру ...

    Вам делать больше нечего???? не хотите помогать--не лезте
  • Rouse_ © (18.08.14 13:52) [19]

    > Я__   (15.08.14 19:51) [11]
    > Мне хочется просто понять принцип создания и вызова немодальных
    > окон из родительского

    На, разбирайся, код наколеночный, но идея думаю понятна: http://rouse.drkb.ru/tmp/amf.zip
  • Я__ (18.08.14 23:27) [20]
    Rouse_ © Спасипо. посмотрим
 
Конференция "WinAPI" » Несколько окон WinAPI
Есть новые Нет новых   [118608   +47][b:0][p:0.006]