當windows客戶區的大小和位置需要重新計算時會發出該訊息,因此,攔截該訊息可以控制windows窗體客戶
區的尺寸和位置。wm_nccalcsize
的定義為:
#define wm_nccalcsize 0x0083c#定義為:
const int wm_nccalcsize = 0x0083;並且當訊息引數wparam為true時,lparam引數為nccalcsize_params型別的指標,該型別包含了可用於計算客戶區大小和位置的資訊。nccalcsize_params的簽名:
typedef struct tagnccalcsize_params nccalcsize_params, *lpnccalcsize_params;c#宣告:
struct nccalcsize_paramsc#對nccalcsize_params的宣告與c/c++的宣告看似有一點點不同,c/c++定義的是rect陣列,而c#struct _rect
則變成了三個單獨的rect欄位,當前效果是一樣的,只不過乙個使用來所有物件,而乙個是自己訪問而已。
也就是前者的rgrc[0]與後者的rcnewwindow對應,前者的rgrc[1]與rcoldwindow對應,和前者的rgrc[2]與
rcclient對應。只所有c#分別定義,主要是為了更好的說明這三個rect分別表示的意思。
第乙個rect或rcnewwindow儲存了窗體被移動或尺寸被修改後的窗體的座標資訊,這是視窗馬上要應用的資訊,即視窗馬上就移動到座標(rcnewwindow.left, rcnewwindow.top),並且尺寸將調整為
(rcnewwindow.right-rcnewwindow.left, rcnewwindow.bottom-rcnewwindow.top);而第二個rect
或rcoldwindow儲存移動前或尺寸被改變前窗體的座標資訊;第三個rect或rcclient儲存了移動前或尺寸修
改前客戶區的座標資訊。如果窗體是子窗體,那麼座標資訊都使相對父窗體的,否則座標是相對於螢幕的。
然而,當訊息處理完畢後,第乙個rect或rcnewwindow則被用來儲存移動後或大小改變後的客戶區的座標
資訊,即計算夠的結果。也可以推測出計算過程使用rcnewwindow座標與當前作業系統和主題下的窗體標題
欄的高度和窗體邊框的厚度等資訊計算得來。假設窗體高度為captionheight,窗體邊框厚度為borderwidth,
那麼客戶區就可以通過公式計算得出客戶區域座標:
client.left = rcnewwindow.left + borderwidth其實窗體邊框厚度和窗體高度都可以從類system.windows.forms.systeminformation中獲取,不過要根據窗體型別和主題等選擇不同的厚度和高度,這裡不再詳細說明。你可以在視窗建立時攔截wm_nccalcsizeclient.top = rcnewwindow.top + borderwidth + captionheight
client.right = rcnewwindow.right - borderwidth
client.bottom = rcnewwindow.bottom - borderwidth
訊息,獲取nccalcsize_params引數,並根據rcnewwindow和rcclient來計算窗體邊框厚度和標題欄
高度。前面的文字目的,主要是為了說明客戶區域的座標資訊,是根據窗體的新座標資訊、窗體邊框厚度和標題欄的高度進行計算得來的。因此我們可以攔截wm_nccalcsize訊息,人為的修改窗體的座標資訊,從而影響客
戶區座標資訊的計算結果。
由前面說的公式可以看出,對新視窗座標的增減就是對客戶區座標的增減,因此,如下攔截訊息**,實現了加寬,加高客戶區的效果:
private void adjustclientrect(ref _rect rcclient)由於客戶區的寬和高都增加了,但窗體大大小和位置並沒有變化,因此執行的效果就如圖所示,左右和下邊框const int wm_nccalcsize = 0x0083;
protected override void wndproc(ref message m)
m.result = new intptr(1);
}break; }
base.wndproc(ref m);
}
的厚度明顯變小,而標題欄沒有變化,因為我們沒有調整rcclient.top欄位。
因此,如果你再重繪窗體,希望窗體在各版本的windows作業系統和主題中表現一致,可以希望保持窗體的版
塊厚度為borderwidth,你就可以這樣來調整**:
int borerwidth = 1;這裡也沒有設定rcclient.top,以為窗體頂部的邊框在標題欄上訪,這裡簡單的修改rcclient.top是達不到預期效果的,需要重繪標題欄才行,可以參見《private void adjustclientrect(ref _rect rcclient)
c#重繪windows窗體標題欄和邊框
》。執行效果如下:
當然,你也可以利用這個方法,在不設定formborderstyle屬性為none的情況下,實現無邊框視窗的效果。
簡單修改**即可實現:
private void adjustclientrect(ref _rect rcclient)雖然通過攔截wm_nccalcsize訊息的方法可以實現修改客戶區域座標、邊框厚度、無邊框等效果,但還是文章開頭所說的,實現在各種windows作業系統版本和主題下統一樣式才是主要應用,當然這只是統一樣式的
一部分,可以統一視窗邊框的厚度,至於窗體的邊框的樣式,甚至整個窗體的樣式,還是需要結合重繪標題欄
和邊框的,如需要,可以參考《
c#重繪windows窗體標題欄和邊框
》的實現。
修改窗體客戶區區域
當windows客戶區的大小和位置需要重新計算時會發出該訊息,因此,攔截該訊息可以控制windows窗體客戶 區的尺寸和位置。wm nccalcsize 的定義為 define wm nccalcsize 0x0083c 定義為 const int wm nccalcsize 0x0083 並且當訊...
視窗區域和客戶區域
getclientrect 此函式用於取得視窗的客戶區座標。客戶區即視窗客戶區的左上角和右下角之間 的區域。客戶區座標的原點位於視窗客戶區的左上角,即用此函式得到的座標的 原點是視窗客戶區的左上角,左上角的的座標值為 0,0 返回值 成功時返回非0,失敗時返回0 注意 在與結構rect之間的轉換中為...
Qt控制項窗體區域區分
控制項窗體區域區分 幾何引數 指的是視窗的大小和位置,乙個視窗有兩套幾何引數,一套是視窗外邊框所佔的矩形區域,另一套是視窗客戶區所佔的矩形區域,所謂視窗客戶區就是視窗中除去邊框和標題欄用來顯示內容的區域 對於乙個視窗部件來說,它的兩套幾何引數是一致的 const qrect geometry con...