Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Управление окном при создании, при запуске приложения появляется 2 окна 
:(
    Опции темы
GGoga
Дата 1.7.2007, 17:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Здравствуйте, уважаемые господа программисты. Помогите разобраться с проблемой начинающему программисту.

А проблема заключается в следующем:
С помощью мастера MFC создаю SDI приложение, представление которого наследую от CFormView. Я хочу, чтобы запускаемое окно имело свойства, которые требуются мне, а именно: положение окна центрировалось относительно экрана, имело высоту и ширину пропорциональную экрану, а также загружало иконку, которую создал я. Чтобы это реализовать, я прописываю следующий код в обработчике InitInstance() класса приложения:
Код

BOOL CEmbadedDBApp::InitInstance()
{
   ...
    // Parse command line for standard shell commands, DDE, file open
    CCommandLineInfo cmdInfo;
    ParseCommandLine(cmdInfo);


    // Dispatch commands specified on the command line.  Will return FALSE if
    // app was launched with /RegServer, /Register, /Unregserver or /Unregister.

// При троссировке первое стандартное окно появляется вот на этой строке!!!
    if (!ProcessShellCommand(cmdInfo))
        return FALSE;


//*******************Мой код***************************//
    // Устанавливаем иконку окна
    m_pMainWnd->SetIcon(LoadIcon(IDI_MY_ICON), TRUE);
    // Устанавливаем окно поверх остальных
    if(!m_pMainWnd->SetForegroundWindow())
        MessageBox(m_pMainWnd->GetSafeHwnd(),_T("Не возможно установить окно поверх остальных окон!"),
        _T("Внимание"), MB_OK | MB_ICONEXCLAMATION | MB_ICONWARNING);
    // Устанавливаем размер окна
    m_pMainWnd->MoveWindow(&m_WRect, TRUE);
    // Центрируем положение окна
    m_pMainWnd->CenterWindow();
//*****************************************************//


    m_pMainWnd->ShowWindow(SW_SHOW);
    m_pMainWnd->UpdateWindow();
    // call DragAcceptFiles only if there's a suffix
    //  In an SDI app, this should occur after ProcessShellCommand
    

    return TRUE;
}



Однако, при запуске программы сначала запускается стандартное окошко (созданное приложением), которое имеет собственные размеры, положение на экране и иконку, потом оно исчезает и запускается мое окно с прописанными свойствами (появление и исчезновение первого окна длится около 1 сек. - мелочь, но не приятно...). Я хочу этого в своем мелком проекте избежать, пусть он хоть и небольшой и пишется для получения навыков в программировании, но будет, по крайней мере, красивым smile

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

Подскажите, кто знает решение проблемы, заранее ОГРОМНОЕ СПАСИБО!!!
PM MAIL ICQ Skype   Вверх
Прохожий
Дата 2.7.2007, 10:02 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



В CMainFrame есть такая функция где и задаётся нужный стиль и положение окна
Код

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    if( !CFrameWnd::PreCreateWindow(cs) )
        return FALSE;
    // TODO: Modify the Window class or styles here by modifying
    //  the CREATESTRUCT cs
//  ....... ВОТ здесь и вставляешь что треба ............
//  ....... Например ....................................................
    cs.dwExStyle |= WS_EX_TOOLWINDOW;
// ......... Это .....
    return TRUE;
}


PM MAIL   Вверх
GGoga
Дата 2.7.2007, 11:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Прохожий @ 2.7.2007,  10:02)
В CMainFrame есть такая функция где и задаётся нужный стиль и положение окна
Код

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    if( !CFrameWnd::PreCreateWindow(cs) )
        return FALSE;
    // TODO: Modify the Window class or styles here by modifying
    //  the CREATESTRUCT cs
//  ....... ВОТ здесь и вставляешь что треба ............
//  ....... Например ....................................................
    cs.dwExStyle |= WS_EX_TOOLWINDOW;
// ......... Это .....
    return TRUE;
}


А как тогда загрузить иконку, чтобы не появлялась иконка по умолчанию? Это можно сделать в PreCreateWindow? И еще такой вопрос: можно ли установить позицию окна в центре относительно экрана не производя расчетов? Просто переменная CREATESTRUCT& cs имеет для этого 2 свойства: x и y, и чтобы разместить собственное окно центрировано, необходимо произвести соответствующие расчеты координат левого верхнего угла прямоугольника... Можно ли это сделать не производя расчетов, в том смысле, есть ли уже какая-нибудь стандартная функция для этого?


Заранее спасибо!
PM MAIL ICQ Skype   Вверх
Прохожий
Дата 2.7.2007, 12:17 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

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

Проще всего заменить имеющуюся своей или использовать 
SetIcon(AfxGetApp()->LoadIcon(IDI_ICON1), FALSE);
Тамже в функции 
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
Цитата

Просто переменная CREATESTRUCT& cs имеет для этого 2 свойства: x и y, и чтобы разместить собственное окно центрировано, необходимо произвести соответствующие расчеты координат левого верхнего угла прямоугольника... Можно ли это сделать не производя расчетов, в том смысле, есть ли уже какая-нибудь стандартная функция для этого?


Есть что-то с ходу не могу сказать. Может как-то можно использовать вот это CenterWindow(CWnd*); навскидку?


Это сообщение отредактировал(а) Прохожий - 2.7.2007, 12:41
PM MAIL   Вверх
GGoga
Дата 2.7.2007, 17:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Прохожий @ 2.7.2007,  12:17)
Проще всего заменить имеющуюся своей или использовать 
SetIcon(AfxGetApp()->LoadIcon(IDI_ICON1), FALSE);
Тамже в функции 
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

Я почему-то в обработчиках данного класса вообще не могу получить указатель на главное окно??? Может я что-то не то делаю?


У меня еще вот такой вопрос: почему я из обработчика BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) не могу получить указатель на главное окно? И вообще, можно ли это сделать?
А делаю я это следующим образом:

Код

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    if(!CFrameWnd::PreCreateWindow(cs))
        return FALSE;

    CWnd* pScreen,
    
Код

//Вот здесь я пытаюсь получить указатель на главное окно:
          *pWnd = AfxGetMainWnd();
    //Проверяю на получение корректного результата:
    if(pWnd != NULL)
        pWnd->CenterWindow();//В итоге окно не центрируется относительно экрана, потому что указатель равен 0!!! И я не знаю, в чем проблема...
            

    // Определение разрешения экрана
    CRect pWndRect;
    if(!(pScreen = GetDesktopWindow()))
    {
        MessageBoxW(_T("Не возможно получить дескриптор экрана. Будут использованы настройки по умолчанию!"),
            _T("Внимание"), MB_OK | MB_ICONEXCLAMATION | MB_ICONWARNING);
        pWndRect.top = 0;
        pWndRect.left = 0;
        pWndRect.bottom = 800;
        pWndRect.right = 600;
    }
    else
        pScreen->GetWindowRect(&pWndRect);

    // Установить ширину и высоту формы
    // Уменьшение размеров окна как 1:1,5 по отношению к экрану
    cs.cx = static_cast<int>(static_cast<double>(pWndRect.right) / 1.5) - 2;
    cs.cy = static_cast<int>(static_cast<double>(pWndRect.bottom) / 1.5)  - 2;
    
Код

    //Приходится центрировать его вручную...
    cs.x = (pWndRect.right - cs.cx) / 2;
    cs.y = (pWndRect.bottom - cs.cy) / 2;

    cs.style = WS_OVERLAPPED | WS_CAPTION | FWS_ADDTOTITLE 
             | WS_MINIMIZEBOX | WS_SYSMENU;
    
    return TRUE;
}




Вот так я пытаюсь (выделено жирным) управлять главным окном из вышеуказанного обработчика, только не могу получить на него (на главное окно) указатель... Подскажите, можно ли так делать, а если можно, то почему в результате возвращается 0-вой результат?

Заранее СПАСИБО!!!

Добавлено через 5 минут и 38 секунд
Иконку сделал как Вы и говорили - изменил ту, что по умолчанию, но все равно, хотелось бы знать, как это можно сделать программно.
PM MAIL ICQ Skype   Вверх
GGoga
Дата 2.7.2007, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Проблему с предыдущим вопросом решил, оказывается, что главное окно еще не существует в момент вызова обработчика BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) класса CMainFrame (формы). И как всегда, решение одного вопроса порождает новый... :( 

А можно ли (если можно, то в каком обработчике) вообще в этом классе (классе формы) в момент, когда окно еще не является видимым для пользователя произвести его настройки (центрировать, установить размеры, загрузить иконку и т.д.)? Просто я еще не совсем разбираюсь с принципами того, как и что за чем вызывается, поэтому, пожалуйста, не удивляйтесь моим столь тупым вопросам... 

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

Заранее СПАСИБО!

PM MAIL ICQ Skype   Вверх
Прохожий
Дата 3.7.2007, 06:53 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

Иконку сделал как Вы и говорили - изменил ту, что по умолчанию, но все равно, хотелось бы знать, как это можно сделать программно. 


Ну я тама указал и програмный способ
вот в ф-и 
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

SetIcon(AfxGetApp()->LoadIcon(IDI_ICON1), FALSE);

А насчёт центрирования окна относительно экрана и вааще определения размеров относительно рабочего стола, просто никогда не занимался. Но может через
 GetDesktopWindow()
Можно получить что.
?
И ещё вот здесь
 http://www.firststeps.ru/ 
почитай тама МНОГО ОТВЕТОВ на МНОГО ВОПРОСОВ  smile 
PM MAIL   Вверх
GGoga
Дата 3.7.2007, 21:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Прохожий @ 3.7.2007,  06:53)
Ну я тама указал и програмный способ вот в ф-и  int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) - SetIcon(AfxGetApp()->LoadIcon(IDI_ICON1), FALSE);

Пробовал так, ничего не получилось :( Так что пришлось менять саму иконку, чтобы не было мелькания.

Добавлено через 4 минуты и 51 секунду
Цитата(Прохожий @ 3.7.2007,  06:53)
А насчёт центрирования окна относительно экрана и вааще определения размеров относительно рабочего стола, просто никогда не занимался. Но может через GetDesktopWindow()

Да именно так я и делал, хотя можно еще так:

Код

CRect workAreaRect;
SystemParametersInfo(SPI_GETWORKAREA, 0, &workAreaRect, 0);
cs.cx = workAreaRect.Width() / 1.5;
cs.cy = workAreaRect.Height() / 1.5;


А вообще все реализовал следующим образом:
Код

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
    if(!CFrameWnd::PreCreateWindow(cs))
        return FALSE;

    CWnd* pScreen;
    
    // Определение разрешения экрана
    CRect pWndRect;
    if(!(pScreen = GetDesktopWindow()))
    {
        MessageBoxW(_T("Не возможно получить дескриптор экрана. Будут использованы настройки по умолчанию!"),
            _T("Внимание"), MB_OK | MB_ICONEXCLAMATION | MB_ICONWARNING);
        pWndRect.top = 0;
        pWndRect.left = 0;
        pWndRect.bottom = 800;
        pWndRect.right = 600;
    }
    else
        pScreen->GetWindowRect(&pWndRect);

    // Установить ширину и высоту формы
    // Уменьшение размеров окна как 1:1,5 по отношению к экрану
    cs.cx = static_cast<int>(static_cast<double>(pWndRect.right) / 1.5) - 2;
    cs.cy = static_cast<int>(static_cast<double>(pWndRect.bottom) / 1.5)  - 2;
    
    cs.x = (pWndRect.right - cs.cx) / 2;
    cs.y = (pWndRect.bottom - cs.cy) / 2;

    cs.style = WS_OVERLAPPED | WS_CAPTION | FWS_ADDTOTITLE 
            | WS_MINIMIZEBOX | WS_SYSMENU;
    
    return TRUE;
}


PM MAIL ICQ Skype   Вверх
Прохожий
Дата 4.7.2007, 12:33 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Ну незнаю чем не работает смена иконки вот как здесь
Код

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
    
    if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
        | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
        !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
    {
        TRACE0("Failed to create toolbar\n");
        return -1;      // fail to create
    }

    if (!m_wndStatusBar.Create(this) ||
        !m_wndStatusBar.SetIndicators(indicators,
          sizeof(indicators)/sizeof(UINT)))
    {
        TRACE0("Failed to create status bar\n");
        return -1;      // fail to create
    }

    // TODO: Delete these three lines if you don't want the toolbar to
    //  be dockable
//==== А ВОТ МЫ ИКОНКУ ПОМЕНЯЛИ ПРИЧЁМ БЕЗ ПРОБЛЕМ =========
    SetIcon(AfxGetApp()->LoadIcon(IDR_TESTSDTYPE), TRUE);
//====================================================

    m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
    EnableDocking(CBRS_ALIGN_ANY);
    DockControlBar(&m_wndToolBar);

    return 0;
}


Работает за всю мазуту  smile 
PM MAIL   Вверх
GGoga
Дата 4.7.2007, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Да, действительно, так иконка устанавливается без проблем. Спасибо за полезный совет!
PM MAIL ICQ Skype   Вверх
Gerk
Дата 9.7.2007, 20:28 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Ну как еще один способ центрирования окна  smile 


Код

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
   // Размер окна будет равен 1/3 и окно будет отцентрировано
   cs.cy = ::GetSystemMetrics(SM_CYSCREEN) / 3;
   cs.cx = ::GetSystemMetrics(SM_CXSCREEN) / 3;
   cs.y = ((cs.cy * 3) - cs.cy) / 2;
   cs.x = ((cs.cx * 3) - cs.cx) / 2;

    return CFrameWnd::PreCreateWindow(cs);
}

PM MAIL   Вверх
Earnest
Дата 10.7.2007, 09:39 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

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



Попробуй еще переопределить функцию CFrameWnd::ActivateFrame: вроде бы она приходит до появления кона на экране, и там можно его отцентровать и т.д. 


--------------------
...
PM   Вверх
GGoga
Дата 11.7.2007, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Gerk @ 9.7.2007,  20:28)
Ну как еще один способ центрирования окна...

Спасибо! Знать лишний способ никогда не помешает smile
PM MAIL ICQ Skype   Вверх
GGoga
Дата 11.7.2007, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Earnest @ 10.7.2007,  09:39)
Попробуй еще переопределить функцию CFrameWnd::ActivateFrame: вроде бы она приходит до появления кона на экране, и там можно его отцентровать и т.д.

Спасибо smile Этот способ тоже работает, только с его помощью центрирование происходит постоянно при активации формы, даже если пользователь переместит окно в другое место, что не очень удобно, хотя знать еще один способ центрирования окна никогда не помешает smile
PM MAIL ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




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


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

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