分享
 
 
 

SDK实现分隔条

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

Windows中的分隔条是一种被广泛使用的控件,绝大多数Explorer式样的应用程序都使用了这种控件。然而却很少有相关的资料对它的完整实现进行介绍,于是我自己实现了一个,希望对SDK的爱好者们有所帮助。

事实上,分隔条也是一个很普通的窗口,它也拥有自己的窗口类、自己的窗口过程——就像所有的预定义控件一样。也就是说,要创建一个分隔条,也需要进行窗口类的注册和窗口的创建。以下的示例代码示范了如何注册一个分隔条的窗口类:

WNDCLASS wc;

wc.cbClsExtra = 0;

wc.cbWndExtra = 0;

wc.hbrBackground = (HBRUSH)COLOR_BTNSHADOW; // 1

wc.hCursor = LoadCursor(NULL, IDC_SIZEWE); // 2

wc.hIcon = NULL;

wc.hInstance = hInstance;

wc.lpfnWndProc = (WNDPROC)ProcSplitter; // 3

wc.lpszClassName = "MySplitter"; // 4

wc.lpszMenuName = NULL;

wc.style = 0;

RegisterClass(&wc);

这段代码相信大家已经很熟悉了,所以在此我只简要说明四点:1、分隔条的背景颜色,这里我取默认的对话框背景色;2、分隔条的鼠标指针,这里我取水平的调整大小指针;3、这是分隔条的窗口过程,所有的秘密都在这个回调函数之中;4、分隔条的窗口类名称,你可以随便取一个你喜欢的名字。

在成功地注册窗口类之后,就可以创建分隔条了。以下是我的示例界面,它由一个树形视图、一个分隔条、一个列表视图以及一个状态栏组成,下文的所有代码都是以这个界面为基础的。

在编写分隔条的窗口过程之前,我先来处理对话框的WM_SIZE消息作为分隔条窗口过程的一个热身。代码如下(你会发现在整个的代码中我没有对hTree、hStatus、hSplitter以及hList做任何的声明,那是因为对于这个简单的示例,我将所有的这些东西都声明为了全局变量):

case WM_SIZE:

{

HDWP hdwp;

RECT rect, rectStatus, rectTree;

hdwp = BeginDeferWindowPos(4);

GetClientRect(hDlg, &rect);

GetClientRect(hStatus, &rectStatus);

GetWindowRect(hTree, &rectTree);

DeferWindowPos(hdwp, hStatus, NULL, 0, rect.bottom - rectStatus.bottom, rect.right, rectStatus.bottom, SWP_NOZORDER);

DeferWindowPos(hdwp, hTree, NULL, 0, 0, rectTree.right - rectTree.left, rect.bottom - rectStatus.bottom, SWP_NOMOVE | SWP_NOZORDER);

DeferWindowPos(hdwp, hSplitter, NULL, rectTree.right - rectTree.left, 0, 2, rect.bottom - rectStatus.bottom, SWP_NOZORDER);

DeferWindowPos(hdwp, hList, NULL, rectTree.right - rectTree.left + 2, 0, rect.right - rectTree.right + rectTree.left - 2, rect.bottom - rectStatus.bottom, SWP_NOZORDER);

EndDeferWindowPos(hdwp);

}

break;

你肯定已经注意到了,这段代码的大部分篇幅都是在和矩形做游戏。的确是这样,因为调整窗口大小的过程就是一个改变各个子窗口的位置和大小的过程。这个过程用语言叙述就是:1、首先,将状态栏放置在对话框的最下方;2、第二步,不改变树形视图的位置和宽度,重设它的高度;3、不改变分隔条的位置和宽度,重设它的高度;4、使列表视图占满剩余的客户区。

如果你弄懂了上面的代码,那么分隔条的窗口过程也就没有任何难度了:

LRESULT CALLBACK ProcSplitter(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)

{

switch (Msg)

{

case WM_LBUTTONDOWN:

SetCapture(hwnd);

break;

case WM_LBUTTONUP:

ReleaseCapture();

break;

case WM_MOUSEMOVE:

{

if ((wParam & MK_LBUTTON) == MK_LBUTTON && GetCapture() == hwnd)

{

HDWP hdwp;

RECT rect, rectStatus, rectTree;

hdwp = BeginDeferWindowPos(3);

GetClientRect(GetParent(hwnd), &rect);

GetClientRect(hStatus, &rectStatus);

GetWindowRect(hTree, &rectTree);

DeferWindowPos(hdwp, hTree, NULL, 0, 0, rectTree.right - rectTree.left + (short)LOWORD(lParam), rect.bottom - rectStatus.bottom, SWP_NOMOVE | SWP_NOZORDER);

DeferWindowPos(hdwp, hSplitter, NULL, rectTree.right - rectTree.left + (short)LOWORD(lParam), 0, 0, 0, SWP_NOSIZE | SWP_NOZORDER);

DeferWindowPos(hdwp, hList, NULL, rectTree.right - rectTree.left + (short)LOWORD(lParam) + 2, 0, rect.right - rectTree.right + rectTree.left - (short)LOWORD(lParam) - 2, rect.bottom - rectStatus.bottom, SWP_NOZORDER);

EndDeferWindowPos(hdwp);

}

}

break;

default:

return DefWindowProc(hwnd, Msg, wParam, lParam);

}

return 0;

}

SetCapture和ReleaseCapture是分别在鼠标左键按下与释放的时候捕获和释放鼠标,这是分隔条的一般要求。这段代码中的核心部分就是在处理鼠标移动的事件,就是当鼠标左键按下并且分隔条捕获鼠标的时候来改变三个相关窗口的位置和宽度。具体的矩形操作与主窗口WM_SIZE的代码原理相似,我就不多说了。我之所以不使用MoveWindow之类的函数来实现改变大小,就是因为这些函数会使窗体的多次重绘而导致整个窗体的闪烁——而事实上我并不希望状态栏也一起闪烁。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有