Windwos SDK开发
--实现超文本的控制
当我们在一个窗口上看见一个链接,我们用鼠标去点击的时候,鼠标会自动改变成"手"状,轻轻一点,马上会启动浏览器,链接到指定的网页,这是怎么实现的呢?请看下面分解:
首先,这个WM_CTLCOLORSTATIC消息时改变STATIC控件或者EDIT控件在只读或者不能使用的时候,在需要重绘时发送给它父窗口的,然后父窗口根据需要更改STATIC控件的TEXT和BACKGROUND,所以当我们在响应主回调函数的时候处理这个消息.
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
//...
switch(msg)
{
case WM_CREATE:
CreateStaticText(hWnd);//创建需要更改的STATIC控件
break;
//...
case WM_CTLCOLORSTATIC:
SetBkMode((HDC)wParam,TRANSPARENT); //改变背景模式为TRANSPARENT
SetTextColor((HDC)wParam,RGB(50,100,150));//设置字体颜色,当然,字体我们也可以改变
break;
//...
}
}
CreateStaticText(hWnd)
{
HWND hStatic;
hStatic=CreateWindow(L"STATIC",L"http://www.microsoft.com",WS_VISIBLE | WS_CHILD | SS_NOTIFY,
100,100,210,22,hWnd,NULL,hInst,NULL);
if( hStatic==NULL )
{
//...; //出错处理
}
StaticOldProc=(WNDPROC)SetWindowLong(hStatic,GWL_WNDPROC,(LONG)StaticControlFun);
}
注意,最后一句是重点,我们通过SetWindowLong来实现窗口的子类化,
我们来简单阐述下"子类化"的意思:当一个窗口创建的时候,需要使用WNDCLASS结构参数调用RegisterClass函数,注册窗口.在这个结构中有一个窗口过程.窗口创建后,当有消息发送到这个窗口时,Windows就会通过这个地址调用窗口,为了实现子类化,我们就需要返回原来的窗口过程地址,利用返回原来的窗口过程地址,应用程序就可以把消息窗地给原来的窗口过程,或者修改消息传递给窗口过程,或者不传.当然,我们不能深入讨论.
GWL_WNDPROC设置一个新的回调函数地址.StaticControlFun就是我们的处理函数,声明为
LRESULT CALLBACK StaticControlFun(HWND, UINT, WPARAM, LPARAM);(是不是和主回调函数一样?)
StaticOldProc是我们需要撤销子类化后恢复的函数地址 声明为WNDPROC StaticOldProc;
我们利用SetWindowLong(hStatic,GWL_WNDPROC,(DWORD)StaticOldProc);就可以去除子类化设置了
好了,我们来处理StaticControlFun函数吧,这里是关键
//StaticControlFun 这里的hWnd都是我们的STATIC控件的句柄,而不是主窗口的
LRESULT CALLBACK StaticControlFun(HWND hWnd,UINT msg ,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_MOUSEMOVE: //响应鼠标移动,更替鼠标模样
SetCursor(LoadCursor(NULL,IDC_HAND));
break;
case WM_LBUTTONDOWN:
ShellExecute(hWnd, TEXT("open"), TEXT("IEXPLORE.EXE"), TEXT("http://www.microsoft.com"), TEXT("C://Program Files//Internet Explorer"), SW_SHOW);
break;
//这个Shell函数就是调用我们的IE,并打开相关网页,具体请查看MSDN
default:
return CallWindowProc(StaticOldProc,hWnd,msg,wParam,lParam);
//类似于DefWindowProc(//...);
}
return 0;
}
好了,我们已经实现了STATIC控件的设置,以及了解了一些窗口子类化,好好领会下窗口子类化,这是一个很重要的技术