手動創建控件的tab順序:
一般手動創建的控件(在其它可視化控件存在的情況下)按tab鍵是不會有焦點的!只要在創建控件的函數Create時
加WS_TABSTOP屬性就會有了!(這個一定要記得要加)
若你想令它成為當窗口彈出來時成為第一個擁有焦點的控件,只要你用下面的函數就可以:
myButton.SetWindowPos(&wndTop,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
SetWindowPos函數的介紹:
BOOL SetWindowPos (
const CWnd* pWndInsertAfter,
int x,
int y,
int cx,
int cy,
UINT nFlags );
這個方法改變子窗口,(右擊)彈出窗口,頂級窗口的大小,位置和Z順序!
從我的看法來覺得,Z順序是相對顯示器平面的垂直方向窗口顯示的順序!
參數:
pWndInsertAfter
在z序中的位于被置位的窗口前一個窗口句柄。該參數必須為一個CWnd指針,或下列值的地址(因為參數是指針)之一:
wndBottom 將窗口置于Z序的底部;如果CWnd是一個頂層窗口,這個窗口將失去頂級位置,它將放在所有窗口的底部!
wndTop 將窗口置于Z序的頂部
wndTopMost 將窗口置于所有非頂層窗口之上。即使窗口未被激活窗口也將保持頂級位置。
wndNoTopMost 將窗口置于所有非頂層窗口之上(即在所有頂層窗口之后)。如果窗口已經是非頂層窗口則該標志不起作用。
wndTop就是要將它放到Z順序的首位置;
x: 以客戶坐標指定窗口新位置的左邊界.
Y: 以客戶坐標指定窗口新位置的頂邊界.
cx:以像素指定窗口的新的寬度.
cy:以像素指定窗口的新的高度.
uFlags:窗口尺寸和定位的標志。該參數可以是下列值的組合:
SWP_ASNCWINDOWPOS:如果調用進程不擁有窗口,系統會向擁有窗口的線程發出需求。這就防止調用線程在其他線程處理需求的時候發生死鎖。
SWP_DEFERERASE:防止產生WM_SYNCPAINT消息。
SWP_DRAWFRAME:在窗口周圍畫一個邊框(定義在窗口類描述中)。
SWP_FRAMECHANGED:給窗口發送WM_NCCALCSIZE消息,即使窗口尺寸沒有改變也會發送該消息。如果未指定這個標志,只有在改變了窗口尺寸時才發送WM_NCCALCSIZE。
SWP_HIDEWINDOW;隱藏窗口。
SWP_NOACTIVATE:不激活窗口。如果未設置標志,則窗口被激活,并被設置到其他最高級窗口或非最高級組的頂部(根據參數hWndlnsertAfter設置)。
SWP_NOCOPYBITS:清除客戶區的所有內容。如果未設置該標志,客戶區的有效內容被保存并且在窗口尺寸更新和重定位后拷貝回客戶區。
SWP_NOMOVE:維持當前位置(忽略X和Y參數)。
SWP_NOOWNERZORDER:不改變z序中的所有者窗口的位置。
SWP_NOREDRAW:不重畫改變的內容。如果設置了這個標志,則不發生任何重畫動作。適用于客戶區和非客戶區(包括標題欄和滾動條)和任何由于窗回移動而露出的父窗口的所有部分。如果設置了這個標志,應用程序必須明確地使窗口無效并區重畫窗口的任何部分和父窗口需要重畫的部分。
SWP_NOREPOSITION;與SWP_NOOWNERZORDER標志相同。
SWP_NOSENDCHANGING:防止窗口接收WM_WINDOWPOSCHANGING消息。
SWP_NOSIZE:維持當前尺寸(忽略cx和cy參數)。
SWP_NOZORDER:維持當前Z序(忽略pWndInsertAfter參數)。
SWP_SHOWWINDOW:顯示窗口。
返回值:如果函數成功,返回值為非零;如果函數失敗,返回值為零。若想獲得更多錯誤消息,請調用GetLastError函數。
備注:如果設置了SWP_SHOWWINDOW和SWP_HIDEWINDOW標志,則窗口不能被移動和改變大小。如果使用SetWindowLoog改變了窗口的某些數據,則必須調用函數SetWindowPos來作真正的改變。使用下列的組合標志:SWP_NOMOVE|SWP_NOSIZE|SWP_FRAMECHANGED。
有兩種方法將窗口設為最頂層窗口:一種是將參數pWndInsertAfter設置為wndTopMost并確保沒有設置SWP_NOZORDER標志;另一種是設置窗口在Z序中的位置以使其在其他存在的窗口之上。當一個窗口被置為最頂層窗口時,屬于它的所有窗口均為最頂層窗口,而它的所有者的z序并不改變。
如果wndTopMost和wndNoTopMost標志均未指定,即應用程序要求窗口在激活的同時改變其在Z序中的位置時,在參數hWndinsertAfter中指定的值只有在下列條件中才使用:
在hWndlnsertAfter參數中沒有設定wndNoTopMost和wndTopMost標志。
由hWnd參數標識的窗口不是激活窗口。
如果未將一個非激活窗口設定到z序的頂端,應用程序不能激活該窗口。應用程序可以無任何限制地改變被激活窗口在Z序中的位置,或激活一個窗口并將其移到最高級窗口的頂部或非最高級窗口的頂部。
如果一個頂層窗口被重定位到z序的底部(wndBottom)或在任何非最高序的窗口之后,該窗口就不再是最頂層窗口。當一個最頂層窗口被置為非最頂級,則它的所有者窗口和所屬者窗口均為非最頂層窗口。
一個非最頂端窗口可以擁有一個最頂端窗口,但反之則不可以。任何屬于頂層窗口的窗口(例如一個對話框)本身就被置為頂層窗口,以確保所有被屬窗口都在它們的所有者之上。
如果應用程序不在前臺,但應該位于前臺,就應調用SetForegroundWindow函數來設置。
我手動創建了幾個控件,然后調用下面的函數進行設置tab順序!未設置之前是按控件的創建順序為tab順序:
void CTest4Dlg::OnSetOrder()
{
CWnd * pNum1=GetDlgItem(IDC_NUM1);
CWnd * pNum2=GetDlgItem(IDC_NUM2);
CWnd * pResult=GetDlgItem(IDC_RESULT);
CWnd * pEqual=GetDlgItem(IDC_EQUAL);
CWnd * pClear=GetDlgItem(IDC_CLEAR);
CWnd * pSetOrder=GetDlgItem(IDC_SETORDER);
EquBtn.SetWindowPos(&wndTop,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);//wndTop是設置為Z順序的最頂部!
Num2.SetWindowPos(pEqual,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
SetOrder.SetWindowPos(pNum2,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
Result.SetWindowPos(pSetOrder,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
Clear.SetWindowPos(pResult,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
}
開始時它的tab順序是這樣的,如下圖:

當按了設置按鈕(OnSetOrder)后,如下圖:
