Рейтинг:
2
Jochen Arndt
Похоже, вы использовали код из статьи CodeProject Сохранение размера позиции и состояния windows в MFC[^] но не прочитал его полностью.
OnShowWindow
возможно, он также вызывается во время выполнения программы, но вы, вероятно, хотите, чтобы он вызывался только при запуске программы. В статье упоминается об этом и приводится код, использующий переменную состояния bOnce
чтобы установить размещение только тогда, когда OnShowWindow
называется первый раз.
[EDIT: другой подход, который я использовал в прошлом]
Сохранить помещение в CMainFrame::OnClose
вместо OnDestroy
.
Установите размещение в CMainFrame::OnCreate
вместо OnShowWindow
Однако при этом будет задана только позиция, а размер будет установлен позже при вызове ShowWindow
от InitInstance
требуя чтобы команда была передана сохранена:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
// ... (call OnCreate of base class)
WINDOWPLACEMENT *lwp;
UINT nl;
if (AfxGetApp()->GetProfileBinary(_T("MainFrame"), _T("WP"), (LPBYTE*)&lwp, &nl))
{
// save show state
m_nCmdShow = lwp->showCmd;
// must set this to normal here
lwp->showCmd = SW_SHOWNORMAL;
SetWindowPlacement(lwp);
delete[] lwp;
}
// ...
}
// To be called from InitInstance()
void CMainFrame::ShowWindowInitial()
{
ShowWindow(m_nCmdShow);
UpdateWindow();
}
BOOL CMyApp::InitInstance()
{
// ...
//CMainFrame pMainFrame = new CMainFrame;
pMainFrame->ShowWindowInitial();
// ...
}
[/РЕДАКТИРОВАТЬ]
Member 13089825
void CMainFrame::OnShowWindow(BOOL bShow, UINT nStatus)
{
CFrameWndEx::OnShowWindow(bShow, nStatus);
статические кумполу типа bool = истина;
если (bShow && !IsWindowVisible()
усилитель&;&амп; кумполу)
{
bOnce = ложь;
WINDOWPLACEMENT *lwp;
UINT nl;
если (AfxGetApp()-&ГТ;GetProfileBinary(то _t("универсальный"), то _t("РГ"), (LPBYTE*)&ампер;живые обои, усилителя;amp; НЛ))
{
SetWindowPlacement(lwp);
удалить[] lwp;
}
}
}
Все тот же вопрос
Jochen Arndt
"вышеприведенный метод возвращает старые значения, но графический интерфейс позиционируется в соответствии с этими значениями"
Можете ли вы попытаться объяснить это другим (лучшим) способом?
Я прочитал это как:
- Возврат старых значений = данные, сохраненные при последнем выходе из программы, считываются: OK
- Но GUI позиционируется в соответствии с этими значениями = ?
"это" тогда будет относиться к считанным данным, которые являются правильными.
Member 13089825
Я прочитал это как:
- Возврат старых значений = данные, сохраненные при последнем выходе из программы, считываются: OK
- Но GUI позиционируется в соответствии с этими значениями = ? графический интерфейс не позиционируется в соответствии со значениями
"это" тогда будет относиться к считанным данным, которые являются правильными.
Jochen Arndt
Я обновил свое решение с помощью кода, используемого одним из моих приложений.
Если это тоже не работает, вам придется использовать отладчик, чтобы проверить, достигает ли ваш код вызова SetWindowPlacement и какие значения установлены.
Member 13089825
положение x и y обновляется правильно но ширина и высота не обновляются
Jochen Arndt
Смотрите мое обновленное решение.
Там x и y (позиция) применяются в OnCreate, а размер применяется при отображении окна.
Member 13089825
привет, Йохен,извини, что побеспокоил тебя
положение экрана, кажется, запоминается правильно, это размер экрана, который не запоминается
Jochen Arndt
Размер экрана неправильно хранится в реестре или он не применяется?
Обратите внимание также, что размер зависит от команды. Так что проверьте и это значение.
Однако мое обновленное решение должно работать.
Member 13089825
Размер экрана неправильно хранится в реестре или он не применяется?
его не применяют
// сохранить показать состояние
m_nCmdShow = wpl->showCmd;// выбрасывание ошибки типа неинициализированной переменной wpl используется
Jochen Arndt
Я еще не опубликовал код для чтения замены, которая обозначена
// Get placement here
Вы должны вставить код, который уже используется вами (читается из реестра). Не забудьте удалить wpl aftwerwards. И не вызывайте UpdateWindow (), когда делаете это из OnCreate().
Member 13089825
void CMainFrame::OnClose()
{
WINDOWPLACEMENT wp;
GetWindowPlacement(&wp);
AfxGetApp()-&ГТ;WriteProfileBinary(то _t("универсальный"), то _t("РГ"), (LPBYTE)&ампер;РГ, оператор sizeof(РГ));
CFrameWndEx::OnClose();
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWndEx::OnCreate(lpCreateStruct) == -1)
возврат -1;
WINDOWPLACEMENT *lwp;
// Получить размещение здесь
UINT nl;
если (AfxGetApp()-&ГТ;GetProfileBinary(то _t("универсальный"), то _t("РГ"), (LPBYTE*)&ампер;живые обои, усилителя;amp; НЛ))
{
m_nCmdShow = lwp->showCmd;// m_nCmdShow я создал локально
// должен установить это в нормальное состояние здесь
lwp->showCmd = SW_SHOWNORMAL;
SetWindowPlacement(lwp);
удалить[] lwp;
}
все тот же вопрос
Jochen Arndt
m_nCmdShow должен быть членом вашего класса CMainFrame.
Вы реализовали CMainFrame::ShowWindowInitial() и вызвали его из InitInstance()?
Именно в этот момент применяется размер (при последующем вызове UpdateWindow (); вы можете поместить вызов также в ShowWindowInitial).
Как уже отмечалось: он здесь работает.
Если у вас все еще есть проблемы, вы должны отладить свое приложение; например, проверив фактические настройки размера на различных этапах.
Member 13089825
void CMainFrame::ShowWindowInitial()
{
OnShowWindow(m_nCmdShow);// мы не имеем какой-либо функции OnShowWindow()право (у нас есть только функции showwindow или OnShowWindow(типа bool bShow, uint с nStatus)
}
Jochen Arndt
Вы правы: там должен быть ShowWindow(int nCmdShow), а не обработчик OnShowWindow ().
Member 13089825
извините,я следовал тому же самому, но это не работает для меня(размер не обновляется в графическом интерфейсе, а позиция обновляется)
извините, что потратил ваше время впустую
Jochen Arndt
Как уже упоминалось: время для отладки.
Вы должны выяснить, где размер не применяется. Например, вы можете проверить размер до и после вызова ShowWindow() с помощью GetWindowRect() и GetWindowPlacement() и сравнить его с ожидаемыми значениями, считанными из реестра.