窗口属性


窗口属性是分配给窗口的任意数据。窗口属性通常是窗口相关的数据的句柄,但也可以是任意的数值。每个窗口属性由一个字符串名称标识。


★使用窗口属性的好处

窗口属性经常用于把数据与一个subclassed窗口或MDI窗口关联,而如果用CreateWindow或窗口类结构指定的额外字节来实现的话,可能就没有那么方便了,原因有两个:


·程序可能不知道有多少额外字节可用,或它们当前的使用情况。通过使用窗口属性,程序不用访问这些额外字节就能把数据与窗口关联起来。


·程序通过偏移来访问额外字节,而窗口属性通过字符串标识来访问,而非偏移。


★指派窗口属性


SetProp函数把属性数据及其字符串标识赋给窗口;GetProp函数获取由特定字符串标识的属性数据;RemoveProp函数销毁窗口和属性数据间的关联。


★遍历窗口属性


EnumProps和EnumPropsEx通过程序定义的回调函数来遍历窗口属性。EnumProps的回调函数的原型是PropEnumProc。EnumPropsEx包含一个额外的参数,用于给回调函数传递自定义数据,其回调函数的原型是PropEnumProcEx。


★添加窗口属性的例子


#define BUFFER 4096
 
HINSTANCE hinst;       // handle of current instance
HWND hwndSubclass;     // handle of a subclassed window
HANDLE hIcon, hCursor;
HGLOBAL hMem;
char *lpMem;
TCHAR tchPath[] = "c:\\winnt\\samples\\winprop.c";
 
// Load resources.
 
hIcon = LoadIcon(hinst, MAKEINTRESOURCE(400));
hCursor = LoadCursor(hinst, MAKEINTRESOURCE(220));
 
// Allocate and fill a memory buffer.
 
hMem = GlobalAlloc(GPTR, BUFFER);
lpMem = GlobalLock(hMem);
lstrcpy(lpMem, tchPath);
GlobalUnlock(hMem);
 
// Set the window properties for hwndSubclass.
 
SetProp(hwndSubclass, "PROP_ICON", hIcon);
SetProp(hwndSubclass, "PROP_CURSOR", hCursor);
SetProp(hwndSubclass, "PROP_BUFFER", hMem);


这段例子加载了一个图标,一个光标,并分配了一个内存缓冲区。然后用SetProp函数来把这些对象的句柄关联到由hwndSubclass标识的窗口。这些窗口属性分别由PROP_ICON, PROP_CURSOR, 和 PROP_BUFFER标识。


★获取窗口属性的例子


#define PATHLENGTH 256
 
HWND hwndSubclass;     // handle of a subclassed window
HANDLE hIconProp, hCursProp;
HGLOBAL hMemProp;
char *lpFilename;
TCHAR tchBuffer[PATHLENGTH];
int nSize;
HDC hdc;
 
// Get the window properties, then use the data.
 
hIconProp = (HICON) GetProp(hwndSubclass, "PROP_ICON");
TextOut(hdc, 10, 40, "PROP_ICON", 9);
DrawIcon(hdc, 90, 40, hIconProp);
 
hCursProp = (HCURSOR) GetProp(hwndSubclass, "PROP_CURSOR");
TextOut(hdc, 10, 85, "PROP_CURSOR", 9);
DrawIcon(hdc, 110, 85, hCursProp);
 
hMemProp = (HGLOBAL) GetProp(hwndSubclass, "PROP_BUFFER");
lpFilename = GlobalLock(hMemProp);
nSize = sprintf(tchBuffer,
    "Path to file:  %s", lpFilename);
TextOut(hdc, 10, 10, tchBuffer, nSize);


这段例子使用GetProp来获取由PROP_ICON, PROP_CURSOR, 和 PROP_BUFFER标识的属性数据。然后把它们显示在窗口客户区。


★列出给定窗口的属性


EnumPropsEx(hwndSubclass, WinPropProc, NULL);
 
// WinPropProc is an application-defined callback function
// that lists a window property.
 
BOOL CALLBACK WinPropProc(
    HWND hwndSubclass,  // handle of window with property
    LPCSTR lpszString,  // property string or atom
    HANDLE hData)       // data handle
{
    static int nProp = 1;    // property counter
    TCHAR tchBuffer[BUFFER]; // expanded-string buffer
    int nSize;               // size of string in buffer
    HDC hdc;                 // device-context handle
 
    hdc = GetDC(hwndSubclass);
 
    // Display window property string in client area.
 
    nSize = sprintf(tchBuffer, "WinProp %d:  %s", nProp++,
        lpszString);
    TextOut(hdc, 10, nProp * 20, tchBuffer, nSize);
 
    ReleaseDC(hwndSubclass, hdc);
 
    return TRUE;
}


这段例子使用EnumPropsEx函数列出由hwndSubclass标识的窗口的所有窗口属性的字符串标识。该函数通过回调函数WinPropProc把字符串显示在窗口客户区。


★删除窗口属性


当窗口销毁时,必须同时销毁赋给它的任何窗口属性。下面的例子使用EnumPropsEx和回调函数DelPropProc来销毁hwndSubclass标识的窗口关联的所有属性。在回调函数中使用了RemoveProp函数。


case WM_DESTROY:
 
    EnumPropsEx(hwndSubclass, DelPropProc, NULL);
 
    PostQuitMessage(0);
    break;
 
// DelPropProc is an application-defined callback function
// that deletes a window property.
 
BOOL CALLBACK DelPropProc(
    HWND hwndSubclass,  // handle of window with property
    LPCSTR lpszString,  // property string or atom
    HANDLE hData)       // data handle
{
    hData = RemoveProp(hwndSubclass, lpszString);
//
// if appropriate, free the handle hData
//
 
    return TRUE;
}


★API函数说明


☆SetProp


BOOL SetProp(
  HWND hWnd,         // handle to window
  LPCTSTR lpString,  // atom or string
  HANDLE hData       // handle to data
);


SetProp添加新的属性或修改已有的属性。如果字符串标识的属性不存在,则添加新的属性,否则替换原有的属性数据。
其中第二个参数lpString可为正常的sz字符串,不过也可以是一个原子(atom)值。在后面的情况下,atom必须是全局atom,存放于lpString的低字中,lpString高字必须为0。

函数返回值表示调用是否成功。


☆GetProp


HANDLE GetProp(
  HWND hWnd,         // handle to window
  LPCTSTR lpString   // atom or string
);


如果成功,返回属性数据,否则返回NULL。


☆RemoveProp


HANDLE RemoveProp(
  HWND hWnd,         // handle to window
  LPCTSTR lpString   // atom or string
);


返回值同GetProp。


☆EnumProps


int EnumProps( 
  HWND hWnd,               // handle to window
  PROPENUMPROC lpEnumFunc  // callback function
);


遍历动作在达到最后一个属性后,或回调过程返回FALSE时结束。
返回最后一次调用的lpEnumFunc的返回值;如果没有任何属性可供遍历,返回-1。


☆PropEnumProc


BOOL CALLBACK PropEnumProc(
  HWND hwnd,           // handle to window
  LPCTSTR lpszString,  // string component
  HANDLE hData         // data handle component
);


返回TRUE继续遍历,返回FALSE停止遍历。
函数实现的限制:
·可以调用RemoveProp,但只能对传入的属性进行RemoveProp
·不可以增加窗口属性


☆EnumPropsEx


int EnumPropsEx(
  HWND hWnd,                  // handle to window
  PROPENUMPROCEX lpEnumFunc,  // callback function
  LPARAM lParam               // application-defined data
);


☆PropEnumProcEx


BOOL CALLBACK PropEnumProcEx(
  HWND hwnd,          // handle to window
  LPTSTR lpszString,  // string component
  HANDLE hData,       // data handle component
  ULONG_PTR dwData    // application-defined data
);