天天看點

VC禁止或允許拖拽改變視窗尺寸

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;

}

}