全要

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_ONITEMICONLVHT_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

要獲取綁定矩形的列表視圖項的部分。它可爲下列值之一:

·

LVIR_BOUNDS

返回整個項的綁定矩形,包括圖標和標籤。

·

LVIR_ICON

返回圖標或小圖標的綁定矩形。

·

LVIR_LABEL

返回項文本的綁定矩形。

 


說明:
在當前視圖中獲取某項的全部或部分的綁定矩形。

 

 

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 種顯示方式
列 表視圖包含一個項目列表,而其中每個項目由圖標、項目名稱和多個子項組成,每一個子項所包含的項目的數目必須相同,屬性相同的每個子項顯示在同一個列中。 列表視圖控件有兩個重要的數據結構LVCOLUMNLVITEMLVCOLUMN 用於定義報表方式下的 的結構;LVITEM 用於定義 的結 構。這兩個結構的定義及說明如下:

typedef struct _LVCOLUMN {
UINT mask;            //
說明此結構中哪些成員是有效的
int fmt;           //
列的對齊方式
int cx;            //
列的初始寬度
LPTSTR pszText; //
列的標題
int cchTextMax;   //pszText
所指向的緩衝區的大小
int iSubItem;      //
與列關聯的子項的索引值,從0 開始
int iImage;           //
與列關聯的圖像列表中指定圖像的索引值
int iOrder;           //
第幾列,0 代表最左一列
} LVCOLUMN, FAR *LPLVCOLUMN;
typedef struct _LVITEM {
UINT   mask;        //
說明LVITEM 結構中哪些成員有效
int    iItem;       //
項目的索引值( 可以視爲行號)0 開始
int    iSubItem;    //
子項的索引值( 可以視爲列號)0 開始
UINT   state;       //
子項的狀態
UINT   stateMask;   //
狀態有效的屏蔽位
LPTSTR pszText;   //
主項或子項的名稱
int    cchTextMax; //pszText
所指向的緩衝區大小
int    iImage;       //
關聯圖像列表中指定圖像的索引值
LPARAM lParam;    //
程序定義的32 位參數
int iIndent;          //
表示圖像位置縮進的單位
} LVITEM, FAR *LPLVITEM;

列表項常用的屬性如下:View 指定程序運行後列表視圖控件最初顯示的方式,可以設置爲Icon (大圖標)、SmallIcon (小圖標)、List (列 表)或Report (報表);Single selection 表示每次只能選中一個項;Auto arrange 使得項目在IconSmall Icon 顯示方式下能夠自動排序;Edit Labels 表示可以編輯項目的卷標;No column header 表示取消控件所有列的標題。

 

GetTextExtent

  函數功能:使用該函數獲得所選字體中指定字符串的高度和寬度

  函數原型:CSize GetTextExtent(LPCTSTR lpszString, int nCount)

  參數:

  lpszString 是字符串的指針

  nCount 是所包括的字符數

  返回值CSize 是包含(cxcy2 個成員的結構,cx 是字符串的寬度,cy 是字符串的高度。

 

CComboBox::SetItemHeight

int SetItemHeight( int nIndex, UINT cyItemHeight );

返回值:
如果下標或高度值無效,則返回CB_ERR 。否則爲0

參數:

nIndex

指明要設置的是組合框中列表項的高度還是編輯控件(或靜態文本)的高度。
如果組合框的風格是CBS_OWNERDRAWVARIABLEnIndex 指定了列表中待設置高度的項的下標。否則nIndex 必須爲0 ,而且要設置的是所有列表項的高度(它們的高度相同)。
如果nIndex-1 ,則將設置組合框中編輯控件或者靜態文本的高度。

cyItemHeight

指定待設置對象的高度(以像素爲單位)。

 

發佈了0 篇原創文章 · 獲贊 2 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章