GetFocus
返回有輸入焦點的窗口,鍵盤輸入發送給這個窗口,整個系統只有一個窗口有輸入焦點 .
GetActiveWindow() 是活動窗口,不一定有輸入焦點,而且每個線程就有一個活動窗口。
GetFocus() 得到的肯定是 ActiveWindow ,但是 GetActiveWindow() 的窗口不一定是有輸入焦點的窗口。
返回值:
如果活動並且無窗口的控件具有當前的鍵盤焦點(由控件的包容器判定),那麼返回該控件;如果它不具有鍵盤焦點,則返回
NULL
。
否則返回具有鍵盤焦點的
CWnd
對象(同
CWnd::GetFocus
)。
說明:
調用該函數判定一個
COleControl
對象是否具有鍵盤焦點。當調用
SetFocus
時,一個活動的無窗口控件獲得鍵盤焦點。
我在改一個程序,動態修改一個對話框界面上元素的位置,自然
Tab Order
的順序也要做動態改動,我就要用
GetFocus()
來判斷當前焦點的位置,可是我發現焦點在編輯框和按鈕上時沒有問題,一旦焦點在
CCombox
框上,
GetFocus()
的返回就有問題,用
UINT nCurrentItem = GetFocus()->
GetDlgCtrlID();
返回的值始終是
1001
,我的界面上有兩個
CCombox
,兩個的返回值都是
1001
,實際上一個是
113
,一個是
114
。
GetFocus()
的返回是什麼
TmpWnd
,實在是搞不懂?
可以提供什麼線索嗎?或者有什麼辦法在程序裏動態調整
Tab Order
?
我設斷點跟了一把
CWnd* pWnd = GetFocus();
CWnd* pWnd1 = GetDlgItem(IDC_COMBO_CLIENT);
GetDlgItem(IDC_COMBO_CLIENT)-> SetFocus();
pWnd = GetFocus();
最後的
pWnd
返回竟然和
pWnd1
不相同
其中,
pWnd
是什麼
CTempWnd
hWnd=0x000f0566
pWnd1
是
CCombox
hWnd=0x001803ac
A combo box consists
of a list box combined with
either a static control or edit
control.
GetFocus
返回的是
combo
box
中的
Edit
的
CWnd
指針。
修改你的程序的最後一句,
pWnd = GetFocus()-> GetParent();
你就會發現
pWnd
和
pWnd1
相同了。
另外,
UINT nCurrentItem = GetFocus()-> GetParent()->
GetDlgCtrlID()
;
這一句可以得到
combo
box
的
ID
。
請問怎麼給對話框中的某個 edit 控件設置焦點 , 我用 setfocus 怎麼不行 , 用 dialog 中的成員函數 GoToDlgCtrl 也不行 , 請問怎麼搞 ?
SetFocus()
函數的正確使用
如果在
InitDialog
中調用此函數將不能實現預期的功能
,
比如
,
在一個登錄的對話框實現
如下功能
:
如果讀取的用戶名不爲空
,
就設置用於輸入口令的控件爲當前控件
,
使用如下
語句在
InitDialog
中時會沒有任何作用
GetDlgItemText(IDC_WL_USERNAME,strName);
if(strName!= " ")
GetDlgItem(IDC_WL_IPASSWORD)-> SetFocus();
原因分析
:
在創建對話框時
,
對話框並沒有顯示出來
,
而此時調用此函數返回的句柄是
NULL
解決方法
:
把這段語句放到重載的函數
OnShowWindow
中
HitText
通過位置得到該項的索引
void CBizmeetDlg::OnClickList2(NMHDR* pNMHDR, LRESULT* pResult)
{
// 取得鼠標的位置
CPoint pt;
GetCursorPos( &pt);
m_listCtrl.ScreenToClient(&pt);
int iIndex = m_listCtrl.HitTest(pt,NULL);
if (- 1 != iIndex )
{
CString strMess ;
strMess.Format( " 你選中第%d 項" ,iIndex);
AfxMessageBox(strMess);
}
*pResult = 0 ;
}
其實關鍵是要有ScreenToClient 這個函數的使用,我先前沒有用這個函數,HitTest 老是返回-1, 搞得我都頭大了。不過這個不能用於SubItem, 那應該要用SubItemHitTest
LVHITTESTINFO ht ;
GetCursorPos(&(ht.pt)) ;
m_friendList.ScreenToClient(&ht.pt) ;
m_friendList.HitTest(&ht) ;
if
(ht.iItem == -1)
//
檢查是否有item
選中
return
;
CListCtrl::HitTest
int HitTest(LVHITTESTINFO* pHitTestInfo) const
int HitTest(CPoint pt,UINT* pFlags=NULL) const
返回值:
返回參數pHitTestInfo
指定位置的項的索引,否則爲-1
。
參數:
pHitTestInfo |
含有要進行擊中測試的位置以及接受擊中測試有關結果信息的LVHITTESTINFO 結構的地址。 |
pt |
被測試的指針。 |
pFlags |
指向接受測試結果信息的整數的指針。請參閱聯機文檔“ 平臺SDK” 中有關LVHITTESTINFO 結構的flags 成員的註解。 |
說明:
如果有,則決定哪一個列表視圖項在指定的位置上。
可以通過使用結構中flags
成員的LVHT_ABOVE,
LVHT_BELOW,LVHT_TOLEFT
以及LVHT_TORIGHT
的值來決定是否滾動列表視圖控件的內容。上述兩種標誌可以自由組合,例如,假設其位於客戶區域的左上角。
可以通過測試結構中flags
成員的LVHT_ONITEM
值來決定是否給定的位置位於列表視圖項的上方。該數值通過結構flags
成員中的 LVHT_ONITEMICON
,LVHT_ONITEMLABEL,LVHT_ONITEMSTATEICON
的值的位或運算而獲取。
ScreenToClient
函數功能:該函數把屏幕上指定點的屏幕座標轉換成用戶座標。
函數原型:BOOL ScreenToClient(HWND hWnd, LPPOINT lpPoint) ;
參數:
hWnd :指向窗口的句柄,此窗口的用戶空間將被用來轉換。
lpPoint :指向POINT 結構指針,該結構含有要轉換的屏幕座標。
返回值:如果函數調用成功,返回值爲非零值,否則爲零。
Windows NT :若想獲得更多錯誤信息,請調用GetLastError 函數。
註釋:該函數應用hWnd 參數標識的窗口和POINT 結構給定的屏幕座標來計算用戶座標,然後以用戶座標來替代屏幕座標,新座標是相對於指定窗口的領域的左上角。
先調用 GetWindowRect 後再調用 ScreenToClient, 這個時候得到的 rect 和直接使用 GetClientRect 得到的值是相等的。有時候需要獲得窗口矩形的大小和客戶區矩形的大小二者的值,故需要分別調用 GetWindowRect 和 GetClientRect 。如果只需要獲得客戶區矩形的大小,調用 GetClientRect 就行了。 GetWindowRect 和 GetClientRect 函數的說明如下:
CWnd::GetClientRect
void GetClientRect( LPRECT lpRect ) const;
Parameters:
lpRect
Points to a RECT structure or a CRect object to receive
the client coordinates. The left and top members will be 0. The right and
bottom members will contain the width and height of the window.
Remarks:
Copies the client coordinates of the CWnd client area into
the structure pointed to by lpRect. The client coordinates specify the
upper-left and lower-right corners of the client area. Since client coordinates
are relative to the upper-left corners of the CWnd client area, the coordinates
of the upper-left corner are (0,0).
CWnd::GetWindowRect
void GetWindowRect( LPRECT lpRect ) const;
Parameters:
lpRect
Points to a CRect object or a RECT structure that will receive the screen coordinates
of the upper-left and lower-right corners.
Remarks:
Copies the dimensions of the bounding rectangle of the CWnd object to the
structure pointed to by lpRect. The dimensions are given in screen coordinates
relative to the upper-left corner of the display screen. The dimensions of the
caption, border, and scroll bars, if present, are included.
GetWindowRect()
得到的是在屏幕座標系下的
RECT
;(
即以屏幕左上角爲原點
)
GetClientRect()
得到的是在客戶區座標系下的
RECT
;
(
即以所在窗口左上角爲原點
)
GetWindowRect()
取的是整個窗口的矩形;
GetClientRect()
取的僅是客戶區的矩形,也就是說不包括標題欄,外框等;
第一個函數獲得的是窗口在屏幕上的位置,得到的結果可能是這樣
CRect(10,10,240,240);
第二個函數和它不同,它只獲得了客戶區的大小,因此得到的結果總是這樣
CRect(0,0,width,height);
ScreenToClient() 就是把屏幕座標系下的 RECT 座標轉換爲客戶區座標系下的 RECT 座標。
The GetClientRect function retrieves the coordinates of a window's client area. The client coordinates specify the upper-left and lower-right corners of the client area. Because client coordinates are relative to the upper-left corner of a window's client area, the coordinates of the upper-left corner are (0,0).
GetClientRect 得到的是客戶區的大小,也就是說這樣得到的左上角永遠是( 0 , 0 )
The GetWindowRect function retrieves the dimensions of the bounding rectangle of the specified window. The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen.
GetWindowRect 是窗口相對於整個屏幕的座標,屏幕左上點爲 0 , 0
相互轉化用 ScreenToClient 或者 ClientToScreen
ClientToScreen
The ClientToScreen function converts the client coordinates of a specified
point to screen coordinates.
BOOL ClientToScreen(
HWND
hWnd, // window handle for source
coordinates
LPPOINT lpPoint //
pointer to structure containing screen coordinates
);
Parameters
hWnd
Handle to the window whose client area is used for the conversion.
lpPoint
Pointer to a POINT structure that contains the client coordinates to be
converted. The new screen coordinates are copied into this structure if the
function succeeds.
Return Values
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero.
雖然存在調用
GetWindowRect
後再調用
ScreenToClient==GetClientRect
,但
ScreenToClient
()和
ClientToScreen()
兩者都是屬於
WINDOWS API
函數,可能是存在一定的冗餘設計,但意義不同。
不過在
.Net Framework
下對
WINDOWS API
函數進行了重新整理和優化,在獲取控件或窗口的屏幕座標和客戶區座標時更方便的多,只需要得到與控件或窗口相對應屏幕座標和客戶區座標屬性值就可以了
。
ScreenToClient
The ScreenToClient function converts the screen coordinates of a specified
point on the screen to client coordinates.
BOOL ScreenToClient(
HWND
hWnd, // window handle for
source coordinates
LPPOINT
lpPoint // address of structure containing coordinates
);
Parameters
:
hWnd
Handle to the window whose client area will be used for the conversion.
lpPoint
Pointer to a POINT structure that contains the screen coordinates to be
converted.
Return Values
:
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero.
例如:右下角座標等於左上角座標加上窗口的尺寸
CRect rt;
GetWindowRect(&rt);
CPoint pt;
pt = rt.BottomRight();
我的總結:
如果需要獲得窗體在屏幕上的位置,使用
GetWindowRect
如果需要獲得窗體的大小,使用
GetClientRect
CHeaderCtrl 收藏
當 CListCtrl 爲 LVS_REPORT 模式時,就需要用到 CHeaderCtrl 取得 CHeaderCtrl 指針: 方法一:
CListCtrl *pListCtrl = (CListCtrl *)GetListCtrl(); CHeaderCtrl *pHeaderCtrl = pListCtrl->GetHeaderCtrl(); ASSERT(pHeaderCtrl); 方法二:
CWnd *pWnd = pListCtrl->GetDlgItem(0); // 注: CListCtrl 分配給 CHeaderCtrl 的 Control ID 一直都是 0 ASSERT(pWnd); CHeaderCtrl *pHeaderCtrl = static_cast(pWnd); ASSERT(pHeaderCtrl);
自定義標頭項的外觀通過在首次創建標頭控件 (CHeaderCtrl::Create) 時設置 dwStyle 參數,可以定義標頭項或標頭控件本身的外觀和行爲。以下是可以設置的樣式的取樣及其用途: • 若要使標頭項看上去像一個普通按鈕,請使用 HDS_BUTTONS 樣式。 如果要採取操作以響應標頭項上的鼠標單擊(如按照特定的列對數據進行排序,像在 Microsoft Outlook 中那樣),請使用此樣式。 • 若要在鼠標光標經過標頭項時給予標頭項 “ 熱跟蹤 ” 的外觀,請使用 HDS_HOTTRACK 樣式。 當指針經過本來是平面的欄中的項時,熱跟蹤顯示三維輪廓。 • 若要指示應隱藏標頭控件,請使用 HDS_HIDDEN 樣式。 HDS_HIDDEN 樣式指示標頭控件用作數據容器而不是可視控件。此樣式不自動隱藏控件,但卻影響 CHeaderCtrl::Layout 的行爲。 WINDOWPOS 結構的 cy 成員中返回的值將是零,表示不應該讓用戶看到此控件。
表頭控制(
CHeaderCtrl
)通常應用在窗口中的文本或數據的列表之上。一般爲數據列的標題,可以包括多個部分,用戶可以拖動每個部分並可以控制每
列的寬度。表頭控制類提供了普通表頭控制的基本方法,只有在
WINDOWS95
以後版本系統中才提供,其方法包含在
afxcmn.h
文件中,一般與標籤控
制(
CTabCtrl)
和列表控制
(CListCtrl)
組合使用。
1.1
表頭控制的對象結構
1.1.1
表頭控制對象的建立方法
CHeaderCtrl &cheaderCtrl
建立表頭控制對象
Create
建立表頭並綁定對象
CHeaderCtrl::Create
的格式如下:
BOOL Create( DWORD dwStyle, const RECT&
rect, CWnd* pParentWnd, UINT nID );
其返回值非零時初始化成功,否則失敗。
參數
dwStyle
用來確定表頭控制類型;
rect
用來確定表頭控制的大小和位置;
ParentWnd
用來確定表頭控制的父窗口;
nID
用來表示表頭控制的標誌。
表頭控制風格包括:
HDS_BUTTONS
表示表頭控制外觀類似按鈕;
HDS_HORZ
表示表頭控制爲水平排列;
HDS_VERT
表示表頭控制爲垂直排列;
HDS_HIDDEN
表示表頭控制爲隱藏模式。
它也可以使用普通類控制風格,包括:
CCS_BOTTOM
設置控制位置在父窗口的底部並與父窗口同樣寬度;
CCS_NODIVIDER
在控制頂部形成兩個像素的高亮區;
CCS_NOHILITE
在控制頂部形成一個像素的高亮區;
CCS_NOMOVEY
在響應
WM_SIZE
消息時重置大小並水平排列;
CCS_NOPARENTALIGN
使控制自動靠近父窗口的頂部或底部;
CCS_NORESIZE
設置初始大小或新值時使控制使用默認寬度和高度;
CCS_TOP
設置在父窗口客戶區域的頂部並與父窗口同樣寬度;
同樣表頭控制也可以使用窗口控制風格,包括:
WS_CHILD
建立一個子窗口,不能用於
WS_POPUP
窗口類型;
WS_VISIBLE
建立一個初始時不可見的窗口;
WS_DISABLED
建立一個初始時無效的窗口;
WS_GROUP
確定可用光標移動的控制羣組;
WS_TABSTOP
確定可用
TAB
控制移動站點;
表頭控制一般分爲兩個步驟,首先確定表頭控制的數據結構,然後建立表頭控制並綁定對象。
1.1.2
表頭控制的屬性
表頭控制的屬性包括取得表頭控制中項目的數量
GetItemCount
、取得表頭控制中某一項目的內容
GetItem
和設置表頭控制中某一項目的內容
SetItem
。
1.1.3
表頭控制的操作方法
表頭控制的操作方法包括向表頭控制中插入一個新項目
InsertItem
、從表頭控制中刪除一個項目
DeleteItem
和繪製表頭中給定的項目
DrawItem
等。
1.2
表頭控制的數據結構
在使用表頭控制時,首先必須建立一個數據結構
HD_ITEM,
其結構定義如下:
typedef struct _HD_ITEM
{ UINT mask; //
結構成員有效控制位
int cxy; //
表頭項目的寬度
LPSTR pszText; //
表頭項目內容
HBITMAP hbm; //
表頭項目的位置句柄
int cchTextMax; //
表頭內容字符串長度
int fmt; //
表頭項目的格式
LPARAM lParam; //
應用程序定義的
32
位數據
} HD_ITEM;
屏蔽控制位說明了數據結構成員中包含的有效數據,可以是下面標誌的組合:
HDI_BITMAP hbm
成員有效
HDI_FORMAT fmt
成員有效
HDI_LPARAM lParam
成員有效
HDI_TEXT pszText
和
cchTextMax
成員有效
HDI_WIDTH cxy
成員有效並確定項目寬度值
格式標誌位
fmt
可以是以下標誌的組合:
HDF_CENTER
表頭項目居中
HDF_LEFT
表頭項目左對齊
HDF_RIGHT
表頭項目右對齊
HDF_BITMAP
表頭顯示一個位圖
HDF_OWNERDRAW
由主窗口自繪表頭項目
HDF_STRING
表頭項目爲一個字符串
1.3
表頭控制的應用技巧
由
於表頭控制無法單獨使用,其主要是配合列表控制和標籤控制,並多以文字表頭應用多見,
InsertItem
、
SetItem
和
GetItem
是常用的方
法,如在列表控制時利用
InsertColumn
屬性就可以增加一個表列的文本標題,具體用法和技巧見列表控制和標籤控制。下面以在列表控制中的增加表列
的方法來具體說明:
lvcol.pszText=
品
名
;//
設置第一列名
lvcol.iSubItem=i; //
表列寬
m_ListCtrl.InsertColumn(i++,&lvcol);//
插入一列
lvcol.pszText=
數
量
;//
第二列名
lvcol.iSubItem=i;
lvcol.cx=70;
m_ListCtrl.InsertColumn(i++,&lvcol);//
插入一列
GetHeaderCtrl():
CListCtrl 控件上邊那一排 Column
CListCtrl::GetItemRect
BOOL GetItemRect(int nItem,LPRECT lpRect,UNIT nCode) const
返回值:如果成功,則返回非零值,否則爲0
。
參數:
nItem |
要獲取位置的項的索引值。 |
|||||||||
lpRect |
接受綁定矩形的RECT 結構的地址。 |
|||||||||
nCode |
要獲取綁定矩形的列表視圖項的部分。它可爲下列值之一:
|
說明:
在當前視圖中獲取某項的全部或部分的綁定矩形。
CHeaderCtrl::GetItemRect
BOOL GetItemRect(int nIndex, LPRECT lpRect) const;
返回值:如果成功,則返回非零值,否則爲0
。
參數:
nIndex |
標頭控件項目基於0 的索引。 |
lpRect |
指向RECT 項目地址的指針,以接收有界矩形的更多信息。 |
說明:
此函數實現Win32
消息HDM_GETITEMRECT
的功能,可參閱聯機文檔“
平臺SDK”
。
CListCtrl::GetItemPosition
BOOL GetItemPosition(int nItem,LPPOINT lpPoint) const
返回值:如果成功,則返回非零值,否則爲0 。
參數: nItem
要獲取位置的項的索引值。
lpPoint
在視圖座標中接受項左上角位置POINT
結構的地址,按視圖座標。
說明:獲取列表視圖項的位置。
//////////////////////////////////////////////////////////////
CListCtrl::GetItemRect
BOOL GetItemRect(int nItem,LPRECT lpRect,UNIT nCode) const
返回值:如果成功,則返回非零值,否則爲0 。
參數: nItem
要獲取位置的項的索引值。
lpRect
接受綁定矩形的RECT
結構的地址。
nCode
要獲取綁定矩形的列表視圖項的部分。它可爲下列值之一:
· LVIR_BOUNDS
返回整個項的綁定矩形,包括圖標和標籤。
· LVIR_ICON
返回圖標或小圖標的綁定矩形。
· LVIR_LABEL
返回項文本的綁定矩形。
說明:
在當前視圖中獲取某項的全部或部分的綁定矩形。
先看看執行是否成功 , 如果成功再看看值是屏幕座標還是窗口座標 , 需要的話自已轉一下 .
列表視圖控件(List Control
)
列表視圖控件是一種非常常用的控件,在需要以報表形式顯示數據時,列表控件通常是最好的選擇,許多專用的數據報表控件,也是在它的基礎上派生而來。與樹視圖類似,列表控件可以由多個子項目組成,並且支持大圖標、小圖標、列表和報表4
種方式顯示信息,如圖1
所示。
圖1
列表視圖的4
種顯示方式
列 表視圖包含一個項目列表,而其中每個項目由圖標、項目名稱和多個子項組成,每一個子項所包含的項目的數目必須相同,屬性相同的每個子項顯示在同一個列中。
列表視圖控件有兩個重要的數據結構LVCOLUMN
和LVITEM
。LVCOLUMN
用於定義報表方式下的“
列”
的結構;LVITEM
用於定義“
項”
的結
構。這兩個結構的定義及說明如下:
typedef struct _LVCOLUMN { |
列表項常用的屬性如下:View 指定程序運行後列表視圖控件最初顯示的方式,可以設置爲Icon (大圖標)、SmallIcon (小圖標)、List (列 表)或Report (報表);Single selection 表示每次只能選中一個項;Auto arrange 使得項目在Icon 和Small Icon 顯示方式下能夠自動排序;Edit Labels 表示可以編輯項目的卷標;No column header 表示取消控件所有列的標題。
GetTextExtent
函數功能:使用該函數獲得所選字體中指定字符串的高度和寬度
函數原型:CSize GetTextExtent(LPCTSTR lpszString, int nCount) ;
參數:
lpszString 是字符串的指針
nCount 是所包括的字符數
返回值CSize 是包含(cx ,cy )2 個成員的結構,cx 是字符串的寬度,cy 是字符串的高度。
CComboBox::SetItemHeight
int SetItemHeight( int nIndex, UINT cyItemHeight );
返回值:
如果下標或高度值無效,則返回CB_ERR
。否則爲0
。
參數:
nIndex |
指明要設置的是組合框中列表項的高度還是編輯控件(或靜態文本)的高度。 |
cyItemHeight |
指定待設置對象的高度(以像素爲單位)。 |