Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > MDI приложение


Автор: vinter 17.8.2006, 13:58
Создал каркас обычным визардом, там есть такая ф-ия создания дочерних окон:
Код

CMainFrame* pFrame = STATIC_DOWNCAST(CMainFrame, m_pMainWnd);
    // create a new MDI child window
    pFrame->CreateNewChild(
        RUNTIME_CLASS(CChildFrame), IDR_graphTYPE, m_hMDIMenu, m_hMDIAccel);

Вопрос как мне получить HWND нового child'a smile 

Автор: Earnest 17.8.2006, 16:52
Так CreateNewChild его тебе и вернет, т.е. возвращается CMDIChildWnd*, но у окна получить дескриптор просто: m_hWnd.

Автор: vinter 17.8.2006, 18:28
т.е
Код

CMDIChildWnd *pChild;
pChild =  pFrame->CreateNewChild(    
        RUNTIME_CLASS(CChildFrame), IDR_graphTYPE, m_hMDIMenu, m_hMDIAccel);
HWND hWnd;
hWnd = pChild->GetSafeHwnd();

я правильно понял?
И еще у меня появился вопрос в MDI при создании дочерних окон появляется меню Window и с ним можно работать, но когда удалть все дочерние окна, а потом снова начать их создавать то Window становится неактивным..Кто нибудь может сталкивлся с этим??

Автор: Earnest 18.8.2006, 11:37
Цитата(vinter @  17.8.2006,  19:28 Найти цитируемый пост)
я правильно понял?

Можно и так. Но вообще-то стоит знать, что член m_hWnd является открытым, и есть еще оператор преобразования, к-й возвращает HWND. Т.е. можно писать еще так:
Код

HWND hWnd = pChild->m_hWnd;
или так:
Код

HWND hWnd = *pChild;

Со вторым - не сталкивалась.

Автор: vinter 18.8.2006, 12:10
спасибо 

Автор: vinter 18.8.2006, 13:18
Еще такая проблема, ставлю в PreCreateWindow() cs.lpszName = "Лошадь";, ноль эмоций, ставит имя которое у него в ресурсах...
Подскажите как исправить...

Автор: Earnest 18.8.2006, 15:01
Поправь имя в ресурсах. Долго объяснять, но сначала ставиться твое "лошадь", а потом фрейморк меняет его на имя из ресурсов. Посмотреть можно код функции UpdateFrameTitle (вроде так) и вокруг.

Автор: vinter 18.8.2006, 18:07
Цитата

Поправь имя в ресурсах

так то понятно но я хочу ,чтобы при создании нового окна у него было уникальное имя, а не у всех одинаковое.. smile 
Цитата

 а потом фрейморк меняет его на имя из ресурсов

Это можно обойти/заблочить??

Автор: Earnest 21.8.2006, 13:12
Можно, если пороешься в исходных текстах MFC: там много всяких виртуальных ручек.
Но сначала подумай, может стандартными средствами обойдешься. Обычно, имя окна == имя документа + некоторый стандартный текст. Тебя не устраивает имя документа? Тогда ищи функцию CFrameWnd::OnUpdateFrameTitle и смотри от нее, что можно изменить.

Автор: vinter 21.8.2006, 13:16
Спасибо за подсказку!

Автор: vinter 24.8.2006, 20:19
появился новый вопрос..
при создании дочернего окна,  его клентская часть создается так:
Код

int CChildFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
        return -1;
    // create a view to occupy the client area of the frame
    if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, 
        CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
    {
        TRACE0("Failed to create view window\n");
        return -1;
    }
    return 0;
}

m_wndView обьект класса CChildView обьявленный в CСhildFrame...
Фрейм создается вот так
Код

void CMainFrame::OnFileNew() 
{
    // create a new MDI child window
    pChildFrm = new CChildFrame;
    if(!pChildFrm->Create(NULL, NULL))
    return;
    pChildFrm->ShowWindow(SW_SHOWMAXIMIZED);
}

теперь вопрос как мне в функции класса CMainFrame получит hWnd, этого окна??


Автор: Earnest 25.8.2006, 07:37
Какого окна? ChildFrm? Имеешь в виду, в других функциях?
Ну, например, есть функция CMDIFrameWnd::MDIGetActive().

Автор: vinter 25.8.2006, 14:57
Earnest огромное тебе спасибо, с этим хоть разобрался..
Появился еще один вопрос, есть такая ф-ия
Код

void CMainFrame::OnToolBar(UINT nID)
{
    pChildWnd = MDIGetActive();
    m_nIndex = nID - ID_BUTTON_PEN;
    for(int i = ID_BUTTON_PEN; i <= ID_BUTTON_ERASE; i++)
        m_ToolBar.GetToolBarCtrl().CheckButton(i, FALSE);
    ::SetClassLong(pChildWnd->GetSafeHwnd(), GCL_HCURSOR, LONG(AfxGetApp()->LoadCursor(aCursors[m_nIndex])));
    BOOL bCheck = m_ToolBar.GetToolBarCtrl().IsButtonChecked(nID);
    m_ToolBar.GetToolBarCtrl().CheckButton(nID, !bCheck);
}

все вроде правильно, а курсор не меняет..Почему такое может происходитьsmile 

Автор: Earnest 25.8.2006, 18:07
Я не уверена, что изменение курсора в классе окна как-то влияет на уже созданное окно...
Что ты вообще хочешь сделать? Менять курсор в зависимости от нажатой кнопки?
Так это делается по-другому:
1) все возможные курсоры загрузи заранее
2) заведи переменную HCURSOR (или индекс текущего курсора) и присваивай ее на OnToolBar
3) обрабатывай в окне OnSetCursor (ставь свой курсор, в смысле SetCursor)

Автор: vinter 25.8.2006, 20:05
Цитата

Я не уверена, что изменение курсора в классе окна как-то влияет на уже созданное окно...

100% влияет..
Вот только у меня два новых вопроса появилось, я понял почему не меняется курсор, так как я меняю его не в клиентской части окна.
Вопрос как получит hWnd клиентской части.
И второй вопрос при изменении курсора фрейма ,изменится ли он при выведении курсора в область фрейма.
Спасибо за внимание.

Автор: Earnest 28.8.2006, 11:22
Цитата(vinter @  25.8.2006,  21:05 Найти цитируемый пост)
100% влияет..

Ну тогда в чем дело?

Цитата(vinter @  25.8.2006,  21:05 Найти цитируемый пост)
 hWnd клиентской части

hWnd у окна одно, т.е. собственно, это и есть окно. А какая там от него часть тебе требуется - твои проблемы.

Второй вопрос не совсем поняла, но курсор оперделяется самым активным верхним окном, над которым он болтается. Т.е. если в фрейме есть вид, то видом.

Автор: vinter 28.8.2006, 17:58
Цитата

hWnd у окна одно, т.е. собственно, это и есть окно

это то понятно , только у меня то дочернее окно состоит из двух частей.. и клиентская часть это отдельное окно со своим hWnd smile 
Цитата

Ну тогда в чем дело?

дело было как раз в том что я пытался установить курсор в окно у которого нет стиля CLIENTEDGE(вроде правильно написал smile )
Сделал одно полноценное окно, без всяких приколов с клиентской частью в виде отдельного окна, и теперь все нормально работает smile 
Так что тема закрыта.
Earnest Еще раз спасибо

Автор: Earnest 29.8.2006, 07:30
Цитата(vinter @  28.8.2006,  18:58 Найти цитируемый пост)
это то понятно , только у меня то дочернее окно состоит из двух частей.. и клиентская часть это отдельное окно со своим hWnd 

Не путай меня, ладно? Достаточно того, что ты себя запутал. Клиентская часть - эта часть окна, это термин, в конце концов. Окно может состоять только из клиентской части - если у него нет рамки и заголовка, или еще какого нестандартного Layout'а. Если у тебя в клиентской части одного окна сидит другое окно - это все равно разные окна. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)