Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сделать ShowModal на WinAPI, используя ::CreateWindowEx() 
V
    Опции темы
Alca
Дата 18.9.2009, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



VC++ 2008. 
Создаю два окна с помощью ::CreateWindowEx(), 2-е окно является дочерним. 
Надо сделать второе окно модальным (не используя диалоги).
Вот как это делается в билдере:
Код

void __fastcall TForm1::Button1Click(TObject *Sender) {
    TForm2 * pFrm2 = new TForm2(0);
    pFrm2->ShowModal();    //<<< пока форма не закроется - след. строка кода не выполниться.
    delete pFrm2;
}

Как это все наваять на чистом апи?


--------------------
PM WWW ICQ Skype Jabber   Вверх
niteo
Дата 18.9.2009, 13:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



При создании окон, нада указать что одно из них - дочернее.
--------------------
Мне чужого лишнего не нада.Ешь ананасы, рябчиков жуй,день твой последний приходит, буржуй...
PM MAIL   Вверх
GremlinProg
Дата 18.9.2009, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Alca @  18.9.2009,  14:58 Найти цитируемый пост)
Как это все наваять на чистом апи?

так же, только вместо  ShowModal поставить локальный цикл обработки сообщений, типа как в WinMain,
но условие выхода их него привязать в какой-нибудь переменной Finished
пусть, к примеру на WM_DESTROY этого окна выполняется Finished = TRUE, тогда цикл может быть такой:
Код

for( Finished = FALSE ; !Finished && ::GetMessage(...) ; ){
  Translate...
  Dispatch...
}

конечно, тогда нужно будет заблокировать остальные окна перед циклом,
и восстановить их после выхода из цикла

получится модальный диалог


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Alca
Дата 18.9.2009, 13:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



Типа так?
Код

function TCustomForm.ShowModal: Integer;
var
  WindowList: Pointer;
  SaveFocusCount: Integer;
  SaveCursor: TCursor;
  SaveCount: Integer;
  ActiveWindow: HWnd;
begin
  CancelDrag;
  if Visible or not Enabled or (fsModal in FFormState) or
    (FormStyle = fsMDIChild) then
    raise EInvalidOperation.Create(SCannotShowModal);
  if GetCapture <> 0 then SendMessage(GetCapture, WM_CANCELMODE, 0, 0);
  ReleaseCapture;
  Include(FFormState, fsModal);
  ActiveWindow := GetActiveWindow;
  SaveFocusCount := FocusCount;
  Screen.FSaveFocusedList.Insert(0, Screen.FFocusedForm);
  Screen.FFocusedForm := Self;
  SaveCursor := Screen.Cursor;
  Screen.Cursor := crDefault;
  SaveCount := Screen.FCursorCount;
  WindowList := DisableTaskWindows(0);
  try
    Show;
    try
      SendMessage(Handle, CM_ACTIVATE, 0, 0);
      ModalResult := 0;
      
      repeat
        Application.HandleMessage;
        
        if (Application.FTerminate) then 
            ModalResult := mrCancel 
        else if (ModalResult <> 0) then 
            CloseModal;
      until (ModalResult <> 0);
      
      Result := ModalResult;
      SendMessage(Handle, CM_DEACTIVATE, 0, 0);
      if GetActiveWindow <> Handle then ActiveWindow := 0;
    finally
      Hide;
    end;
    
  finally
    if Screen.FCursorCount = SaveCount then
      Screen.Cursor := SaveCursor
    else Screen.Cursor := crDefault;
    EnableTaskWindows(WindowList);
    if Screen.FSaveFocusedList.Count > 0 then
    begin
      Screen.FFocusedForm := Screen.FSaveFocusedList.First;
      Screen.FSaveFocusedList.Remove(Screen.FFocusedForm);
    end else Screen.FFocusedForm := nil;
    if ActiveWindow <> 0 then SetActiveWindow(ActiveWindow);
    FocusCount := SaveFocusCount;
    Exclude(FFormState, fsModal);
  end;
end;



--------------------
PM WWW ICQ Skype Jabber   Вверх
GremlinProg
Дата 18.9.2009, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



да, можно и за борландом повторить
Finished === ModalResult


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Alca
Дата 18.9.2009, 13:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



GremlinProg, спасибо. И даже работает....  smile 

Это сообщение отредактировал(а) Alca - 18.9.2009, 13:59


--------------------
PM WWW ICQ Skype Jabber   Вверх
Emura
Дата 7.3.2010, 00:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Alca, GremlinProg,
думаю задача близка, как можно  сделать такую весчЪ -

есть главное окно, и несколько второстепенных, живущих вне главного(т.е. не внутри). 
второстепенные должны всегда находиться выше главного (даже если фокус на главном)
вот как такое сделать? 

что-то ничего толкового в голову не приходит, эксперименты успехом не увенчались)
спасибо!



PM   Вверх
GremlinProg
Дата 7.3.2010, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



это скорее всего решается проще: можно эти два второстепенных сделать попапами (при создании включить флаг WS_POPUP и указать в hwndParent главное окно )


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Emura
Дата 8.3.2010, 03:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



GremlinProg
всё перепробовал, но не видел желаемого из-за конфликтов стилей(как сейчас понял). на чистом проекте без оберток всё получилось! дело за "малым" осталось найти глючок в ООП обертке. Cпасибо!  smile 
PM   Вверх
Emura
Дата 29.4.2010, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



уважаемые, подскажите, пожалуйста, 
для реализации модальности окна этого достаточно или чего-то упустил?

Код

                ::MSG msg;
                ZERO( &msg, sizeof(msg) );
                while( ::GetMessageW( &msg, null, 0, 0 ) &&    m_modalLoopOn )
                {
                    ::TranslateMessage( &msg );
                    ::DispatchMessageW( &msg );
                }




ps. это ищется корень проблемы описанной тут static указатель

Это сообщение отредактировал(а) Emura - 29.4.2010, 22:30
PM   Вверх
Alca
Дата 29.4.2010, 22:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



У меня так работает:
Код

BOOL CXWindowImpl::bShowModal() {
    /*DEBUG*/xASSERT_RET(NULL != _m_hWnd, NULL);

    MSG msgMsg = {0};   

    _m_bRes = bShow(SW_SHOW);
    xCHECK_RET(FALSE == _m_bRes, FALSE);

    for (_m_bIsDestroyed = FALSE; !_m_bIsDestroyed && ::GetMessage(&msgMsg, NULL, 0, 0); ) {
        ::TranslateMessage(&msgMsg);
        ::DispatchMessage (&msgMsg);
    }

    return _m_bIsDestroyed;
}



--------------------
PM WWW ICQ Skype Jabber   Вверх
Emura
Дата 29.4.2010, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Alca,
спасибо! 
вроде то же самое только немного в профиль...

идеально работает? никаких ошибок не выскакивало при таком подходе?

Это сообщение отредактировал(а) Emura - 29.4.2010, 22:24
PM   Вверх
Alca
Дата 29.4.2010, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

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



Не замечал


--------------------
PM WWW ICQ Skype Jabber   Вверх
Emura
Дата 29.4.2010, 22:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Alca,
спасибо за инфу.

PM   Вверх
GremlinProg
Дата 30.4.2010, 09:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Emura @  30.4.2010,  00:05 Найти цитируемый пост)
ps. это ищется корень проблемы описанной тут static указатель

если я все правильно понял, то это довольно распространенная ошибка,
связанная например с записью за пределами распределенной памяти,
например такое к ней так же может привести:
Код

char*ch1 = new char[10];
for( int i = 20 ; i-- ; ){
  ch1[i] = '!';
}
char*ch2 = new char[10];
...

если не проявится в цикле (что оч. хорошо), проявится на операторе new (и хорошо, если он будет сразу за циклом - найти проще),
т.е. к API проблема не относится,
ищи "хитрый" код, и объясняй ему что надо быть проще :)


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

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


 




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


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

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