1 使用MFC:PreCreateWindow中添加:
固定大小:cs.style=WS_OVERLAPPED | WS_SYSMENU |WS_MINIMIZEBOX ;
可改變大小,把如上改為:
cs.style=WS_OVERLAPPED | WS_SYSMENU |WS_MINIMIZEBOX | WS_THICKFRAME; 這樣的視窗MaxBox為disabled..
2 WIN32 API方式:
調用CreateWindowEx函數前,設定WNDCLASS參數,同上面;
其實方法很多的,這裡列出幾個比較常見的方法來,這裡是以SDI的架構視窗為例子來試驗的。
1.建立一個最大化的視窗,并且不能改變其大小
那麼首先,
app的InitInstance中 在原來pMainFrame->ShowWindow(m_nCmdShow); 的前面加上 DWORD dwStyle = GetWindowLongm_pMainWnd->m_hWnd, GWL_STYLE); // dwStyle &= ~(WS_SIZEBOX); dwStyle &= ~(WS_MAXIMIZEBOX); dwStyle &= ~(WS_MINIMIZEBOX); SetWindowLong(m_pMainWnd->m_hWnd, GWL_STYLE, dwStyle);
m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED); 然後把m_pMainWnd->ShowWindow(m_nCmdShow);可以删了
這裡我把dwStyle &= ~(WS_SIZEBOX);注釋調了,因為把這個屬性去掉的話,會産生麻煩,就是我這個視窗最大話顯示的時候,會把工作列也遮了,靠,實在是另人郁悶但是如果不把這個屬性去掉的話,那麼通過拖拉,還是可以改變這個視窗的大小的,那怎麼辦呢,真傷腦筋阿,換個思路吧
一般視窗大小的改變,都是使用者拖動視窗邊框而造成的。是以,我們可以截獲主視窗消息WM_NCHITTEST在其響應函數中判斷CWnd::OnNcHitTest()的傳回值是否為HTRIGHT,HTLEFT,HTTOP,HTBOTTOM四個值之一,如果是,說明使用者此時已點選了四個邊框之一,此時我們應該傳回HTCLIENT.那麼,滑鼠的形狀就不會變成水準或垂直的雙向箭頭,使用者就不可能依靠拖動邊框來改變視窗大小了。
用class wizard看了以下,竟然沒有找到WM_NCHITTEST這個消息,郁悶,隻能手動添加消息映射了
在BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)下添上 ON_WM_NCHITTEST()
在架構類的頭檔案下聲明 afx_msg UINT OnNcHitTest(CPoint point);
實作
UINT CMainFrame::OnNcHitTest(CPoint point) { if(CWnd::OnNcHitTest(point) == HTRIGHT || CWnd::OnNcHitTest(point) == HTLEFT || CWnd::OnNcHitTest(point) == HTTOP || CWnd::OnNcHitTest(point) == HTBOTTOM) return HTCLIENT;
return CWnd::OnNcHitTest(point); } 這樣好了嗎,沒這隻是限制了四條邊,雖然不能拖拉四條邊了,但是四個角阿呢,郁悶,真麻煩
再加上 HTTOPLEFT HTTOPRIGHT HTBOTTOMLEFT HTBOTTOMRIGHT
這樣4邊+4角,靠,看你怎麼玩
圓滿了嗎??沒,還缺一點點 ,缺什麼輕按兩下視窗最上方也就是caption區域時視窗會變小,而且沒辦法回複怎麼辦??涼拌………………
有辦法的啦
添加ON_WM_NCLBUTTONDBLCLK消息 void CMainFrame::OnNcLButtonDblClk(UINT nFlags, CPoint point) { if(nFlags != HTCAPTION) CFrameWnd::OnNcLButtonDblClk(nFlags, point); } 手動添加一下 WM_NCLBUTTONDBLCLK 這個消息的處理 記得BEGIN_MESSAGE_MAP 那邊要加 ON_WM_NCLBUTTONDBLCLK
這也是手動添加了消息映射,處理以下,ok,搞定,手工
2.建立一個不可改變大小的視窗,哦,yeah,這個簡單了
app的InitInstance中 在原來pMainFrame->ShowWindow(m_nCmdShow); 的前面加上 DWORD dwStyle = GetWindowLongm_pMainWnd->m_hWnd, GWL_STYLE); dwStyle &= ~(WS_SIZEBOX); SetWindowLong(m_pMainWnd->m_hWnd, GWL_STYLE, dwStyle);
m_pMainWnd->ShowWindow(SW_SHOW);
如果還想把最大,最小話視窗去掉,再加上這個 dwStyle &= ~(WS_MAXIMIZEBOX); dwStyle &= ~(WS_MINIMIZEBOX); 把 (WS_SIZEBOX)去掉以後,我們就不能改變視窗大小了,
當然,也可以用WM_NCHITTEST的方法了
3.限制視窗的大小範圍
響應WM_GETMAXMININFO 的消息
處理之 void CMainFrame::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) { // TODO: Add your message handler code here and/or call default lpMMI->ptMinTrackSize.x = 100 ; lpMMI->ptMinTrackSize.y = 100 ; lpMMI->ptMaxTrackSize.x = 200 ; lpMMI->ptMaxTrackSize.y = 200;
CFrameWnd::OnGetMinMaxInfo(lpMMI); }
這樣的話,視窗就被我框死啦,嘿嘿長和寬的範圍都是100-200
當然 MINMAXINFO這個結構體内容也是非常豐富的,可以做的事很多,具體可以察msdn了。
————————————————————————————————————————————————
還有一篇參考MSDN,講當視窗的大小改變後,如何控制視窗的控件變化:
http://blog.csdn.net/starlee/archive/2006/04/17/666222.aspx
_____________________________________________________________________
LONG style = ::GetWindowLong(this-> m_hWnd,GWL_STYLE);
style &= ~(WS_DLGFRAME | WS_THICKFRAME);
SetWindowLong(this-> m_hWnd,GWL_STYLE, style);
this-> ShowWindow(SW_SHOWMAXIMIZED);
CRect rect;
this-> GetWindowRect(&rect);
::SetWindowPos(this-> m_hWnd,HWND_NOTOPMOST,rect.left-1, rect.top-1, rect.right-rect.left + 3, rect.bottom-rect.top + 3, SWP_FRAMECHANGED);
style &= ~(WS_DLGFRAME | WS_THICKFRAME);
是可以達到要求。但用了後就出現了新問題
我是想最大化時無法拖動邊框,但還原後可以拖動,
我在還原響應裡用了
GetWindowLong(..style);
style |= WS_DLGFRAME | WS_THICKFRAM;
SetWindowLong(..style);
發現style無法改回來,邊框還是跟最大化一樣沒了
style |= WS_DLGFRAME | WS_THICKFRAME;
SetWindowLong(this-> m_hWnd, GWL_STYLE, style);
this-> ShowWindow(SW_NORMAL);
試過了,重設的Style沒起作用,暈了
這消息響應是放在CMainFrame下的一個dialogBar裡,難道跟這個有關嗎?
可是為什麼
style &= ~(WS_DLGFRAME | WS_THICKFRAME);起作用了
而 style |= WS_DLGFRAME | WS_THICKFRAME;不起作用呢?
代碼貼出來給看看:
void CShapeDialogBar::OnShapeButtonCommand(CString sShapeName)
{
if(sShapeName==_T( "MAXMIZE "))
{
CWnd* pParent=GetParent();//取得CMainFrame指針
LONG nStyle=GetWindowLong(pParent-> GetSafeHwnd(),GWL_STYLE);
if(!m_bMWndMaxed) //BOOL m_bWndMaxed,訓示視窗狀态
{
pParent-> GetWindowRect(&m_rcOriMainWnd);
CRect rcWorkArea;
SystemParametersInfo(SPI_GETWORKAREA,0,&rcWorkArea,0);
pParent-> MoveWindow(&rcWorkArea);
nStyle &= ~( WS_DLGFRAME | WS_THICKFRAME );
}
else
{
pParent-> MoveWindow(&m_rcOriMainWnd);
pParent-> CenterWindow();
nStyle |= WS_DLGFRAME | WS_THICKFRAME ;
}
SetWindowLong(pParent-> GetSafeHwnd(),GWL_STYLE,nStyle);
pParent-> ShowWindow(SW_NORMAL);
m_bMWndMaxed=!m_bMWndMaxed;
}
}