绿玻璃界面已实现,现跟高手请教更高级的界面

srxumin 2009-08-05 11:06:30
我的笔记在
http://blog.csdn.net/srxumin/archive/2009/08/05/4410917.aspx

现在的问题是,将对话框用dwExStyle|0x80000设置成层级窗体后,对话框就无法像QQ聊天窗口那样通过鼠标进行拉升了,我该怎么办呢?如果需要源代码,请留下邮箱,前提是要和我一起研究这个界面问题呀
...全文
712 37 打赏 收藏 转发到动态 举报
写回复
用AI写文章
37 条回复
切换为时间正序
请发表友善的回复…
发表回复
srxumin 2009-08-10
  • 打赏
  • 举报
回复
果然成功,厉害!!!
Fireway2008 2009-08-09
  • 打赏
  • 举报
回复
呵呵, 楼上果然博学!
想到这个方案的时候,也不知道它就是所谓的“九宫格”,


明确地说:
1~8的外围区域,可以拉伸改变其大小而不改变其位置,
内部的区域,可以拖拉窗口改变其位置而不改变其大小。
Fireway2008 2009-08-09
  • 打赏
  • 举报
回复
用以下代码实现拖拉后图片随之拉伸:


void CTestDlg::ReInitBkgnd()
{
if(m_hdcMemory){
// 重新分配内存DC进行绘制,并刷新
::DeleteDC(m_hdcMemory);
Invalidate();
// 绘制内存位图
HDC hdcTemp = GetDC()->m_hDC;
m_hdcMemory = CreateCompatibleDC(hdcTemp);
HBITMAP hBitMap = CreateCompatibleBitmap(hdcTemp, 500, 500);
SelectObject(m_hdcMemory, hBitMap);
::DeleteObject(hBitMap);
::DeleteDC(hdcTemp);
}

// 再次使用GDI+载入PNG图片
HDC hdcScreen = ::GetDC(m_hWnd);
RECT rct;
GetWindowRect(&rct);
POINT ptWinPos = {rct.left, rct.top};
Graphics graph(m_hdcMemory); //GDI+中的类
Image image(L"bk.png",TRUE); //GDI+中的类
int wndWidth = rct.right-rct.left;
int wndHeight = rct.bottom-rct.top;
graph.DrawImage(&image, 0,0, wndWidth,wndHeight);

// 使用UpdateLayerWindow进行窗口透明处理
HMODULE hFuncInst = ::LoadLibrary(_T("User32.DLL"));
typedef BOOL (WINAPI *MYFUNC)(HWND, HDC, POINT*, SIZE*, HDC, POINT*, COLORREF, BLENDFUNCTION*, DWORD);
MYFUNC UpdateLayeredWindow;
UpdateLayeredWindow = (MYFUNC)GetProcAddress(hFuncInst, _T("UpdateLayeredWindow"));
SIZE sizeWindow= {wndWidth, wndHeight};
POINT ptSrc = {0,0};
UpdateLayeredWindow( m_hWnd, hdcScreen, &ptWinPos, &sizeWindow, m_hdcMemory, &ptSrc, 0, &m_Blend, 2);
GetWindowRect(&m_oldRect); //记录窗体初始化大小的位置
::ReleaseDC(m_hWnd, hdcScreen);
::DeleteDC(hdcScreen);
::FreeLibrary(hFuncInst);

}


调用的时候:



void CTestDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
CRect oldRect;
GetClientRect(&oldRect);
if(GetCapture()==this)
{
if(m_bLDown&& m_bDrag)
{
GetWindowRect(&m_oldRect);
BringWindowToTop();
ReleaseCapture();
m_bLDown = FALSE;
m_bDrag = FALSE;
return;
}
if(m_bLDown&& !m_bDrag)
{
……
ReleaseCapture();
m_bLDown = FALSE;
m_bDrag = FALSE;
ReInitBkgnd();
for(int i=0; i<9; ++i){
m_bArea[i]=false;
}
}
}
CDialog::OnLButtonUp(nFlags, point);
}
dronly 2009-08-08
  • 打赏
  • 举报
回复
我是来学习的。
Conry 2009-08-08
  • 打赏
  • 举报
回复
[Quote=引用 32 楼 srxumin 的回复:]
引用 31 楼 fireway2008 的回复:
目前能想到的是,将图片分两层,边界一层划分为8个区域,如下:
C/C++ code//-------------------------------------------------------------// 以下为划分思路标准//|----|--------------------------------|----|//|_1__|_____________2__________________|_3__|//|    |                                |    |//|    |                                |    |//|  4 |          可拖拉区域          |  5 |//|    |                |    |//|____|________________________________|____|//|  6 |            7                  | 8  |//|----|--------------------------------|----|//-------------------------------------------------------------

1. 点击拖拉的时候,利用SetCapture()捕获鼠标,即使其到了客户区外也没关系;
2. 拖拉的时候,用DrawDragRect画一个虚框;
3. 释放鼠标的时候,利用if(GetCapture()==this)判断鼠标位置,并以8个区域位置为参考,计算此时拖拉后生成的新窗体区域大小;
4. 利用SetWindowPos或者 MoveWindow 进行新窗体的大小和位置设置

目前只能想到如此处理,有点复杂,还未想到更好的方法。


确实很复杂啊,你快变成Windows图形界面的设计师了,哈哈。
[/Quote]

这在换肤里面被称作“九宫格”,好多换肤的都是按这个原理做的
srxumin 2009-08-08
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 ringphone 的回复:]
这个我也自己实现过,不过是MDI窗口,原理是一样的,先创建一个WS_OVERLAPPEDWINDOW类型的窗口做底,之所以这个类型是因为支持调整窗口大小。贴透明PNG,不过贴图的时候需要把背景图4个圆角切割出来贴到4角,然后4边拉伸绘制。响应WM_NCCALCSIZE,WM_NCPAINT自绘标题栏,你这个不难,WM_NCCALCSIZE把标题栏区域去掉就OK。MDI窗口为POPUP类型,去掉标题栏盖到前面,然后设置联动。

你的问题就是把做底的窗口设置成能调整尺寸的类型,如果有标题栏就响应WM_NCCALCSIZE把标题栏去掉。不然就要自己处理鼠标消息来模拟实现调整尺寸的过程。
[/Quote]

我刚试了你的方法,将底部窗体通过属性窗口设置成overlapped,但还是无法拉升,鼠标的拉升双向箭头也没有出现。
最主要的原因是窗口设置成了层级窗体,就不再支持拉升,似乎跟那些属性没关系了
如果你这种方法行,就好人做到底,给个示例好吗?先谢过了
srxumin 2009-08-08
  • 打赏
  • 举报
回复
[Quote=引用 31 楼 fireway2008 的回复:]
目前能想到的是,将图片分两层,边界一层划分为8个区域,如下:
C/C++ code//-------------------------------------------------------------// 以下为划分思路标准//|----|--------------------------------|----|//|_1__|_____________2__________________|_3__|//| | | |//| | | |//| 4 | 可拖拉区域 | 5 |//| |                | |//|____|________________________________|____|//| 6 | 7 | 8 |//|----|--------------------------------|----|//-------------------------------------------------------------

1. 点击拖拉的时候,利用SetCapture()捕获鼠标,即使其到了客户区外也没关系;
2. 拖拉的时候,用DrawDragRect画一个虚框;
3. 释放鼠标的时候,利用if(GetCapture()==this)判断鼠标位置,并以8个区域位置为参考,计算此时拖拉后生成的新窗体区域大小;
4. 利用SetWindowPos或者 MoveWindow 进行新窗体的大小和位置设置

目前只能想到如此处理,有点复杂,还未想到更好的方法。
[/Quote]

确实很复杂啊,你快变成Windows图形界面的设计师了,哈哈。
Fireway2008 2009-08-08
  • 打赏
  • 举报
回复
目前能想到的是,将图片分两层,边界一层划分为8个区域,如下:

//-------------------------------------------------------------
// 以下为划分思路标准

//|----|--------------------------------|----|
//|_1__|_____________2__________________|_3__|
//| | | |
//| | | |
//| 4 | 可拖拉区域 | 5 |
//| |                | |
//|____|________________________________|____|
//| 6 | 7 | 8 |
//|----|--------------------------------|----|

//-------------------------------------------------------------


1. 点击拖拉的时候,利用SetCapture()捕获鼠标,即使其到了客户区外也没关系;
2. 拖拉的时候,用DrawDragRect画一个虚框;
3. 释放鼠标的时候,利用if(GetCapture()==this)判断鼠标位置,并以8个区域位置为参考,计算此时拖拉后生成的新窗体区域大小;
4. 利用SetWindowPos或者 MoveWindow 进行新窗体的大小和位置设置


目前只能想到如此处理,有点复杂,还未想到更好的方法。
srxumin 2009-08-08
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 fireway2008 的回复:]
兄弟,今天在尝试修改你的那个工程,发现了新问题,
主要在BOOL CTestDlg::OnInitDialog()内出现资源泄露!
修改以下2个位置即可:
1. //绘制内存位图
HDC hdcTemp=GetDC()->m_hDC;
m_hdcMemory=CreateCompatibleDC(hdcTemp);
HBITMAP hBitMap=CreateCompatibleBitmap(hdcTemp,500,500);
SelectObject(m_hdcMemory,hBitMap);
::DeleteObject(hBitMap);
::DeleteDC(hdcTemp);

2. .....
        ::ReleaseDC(m_hWnd, hdcScreen);
::FreeLibrary(hFuncInst);
return TRUE;  // return TRUE  unless you set the focus to a control
    }

另外,对于窗体拖拉,当鼠标到达边缘出现变化的拉伸鼠标箭头,我已经取得初步进展,相信不久即可完成拉伸效果。
主要还是在主对话框内响应WM_MOUSEMOVE, WM_LBUTTONDOWN+ WM_lBUTTONUP;
去实现。
[/Quote]


我还没注意有资源泄漏,谢了
到时候等候你佳音
Fireway2008 2009-08-08
  • 打赏
  • 举报
回复
兄弟,今天在尝试修改你的那个工程,发现了新问题,
主要在BOOL CTestDlg::OnInitDialog()内出现资源泄露!
修改以下2个位置即可:

1. //绘制内存位图
HDC hdcTemp=GetDC()->m_hDC;
m_hdcMemory=CreateCompatibleDC(hdcTemp);
HBITMAP hBitMap=CreateCompatibleBitmap(hdcTemp,500,500);
SelectObject(m_hdcMemory,hBitMap);
::DeleteObject(hBitMap);
::DeleteDC(hdcTemp);

2. .....
::ReleaseDC(m_hWnd, hdcScreen);
::FreeLibrary(hFuncInst);
return TRUE; // return TRUE unless you set the focus to a control
}

另外,对于窗体拖拉,当鼠标到达边缘出现变化的拉伸鼠标箭头,我已经取得初步进展,相信不久即可完成拉伸效果。
主要还是在主对话框内响应WM_MOUSEMOVE, WM_LBUTTONDOWN+ WM_lBUTTONUP;
去实现。
ringphone 2009-08-07
  • 打赏
  • 举报
回复
这个我也自己实现过,不过是MDI窗口,原理是一样的,先创建一个WS_OVERLAPPEDWINDOW类型的窗口做底,之所以这个类型是因为支持调整窗口大小。贴透明PNG,不过贴图的时候需要把背景图4个圆角切割出来贴到4角,然后4边拉伸绘制。响应WM_NCCALCSIZE,WM_NCPAINT自绘标题栏,你这个不难,WM_NCCALCSIZE把标题栏区域去掉就OK。MDI窗口为POPUP类型,去掉标题栏盖到前面,然后设置联动。

你的问题就是把做底的窗口设置成能调整尺寸的类型,如果有标题栏就响应WM_NCCALCSIZE把标题栏去掉。不然就要自己处理鼠标消息来模拟实现调整尺寸的过程。
superdiablo 2009-08-06
  • 打赏
  • 举报
回复
不错
hello101105 2009-08-06
  • 打赏
  • 举报
回复
qinxingli@yeah.net,希望楼主传一份,共同研究。
sanguomi 2009-08-06
  • 打赏
  • 举报
回复
这样效果不难的
关键是自己贴图,设置窗口全透明,如果子控件要半透明的地方,先把子控件做透明做透明,弄张全透明的PNG图片,再稍微加点颜色就可以,然后贴到子控件上就可以

Quers 2009-08-06
  • 打赏
  • 举报
回复
不错。。。。
Fireway2008 2009-08-06
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 conry 的回复:]
C/C++ codeclass CMyDlg:public CDialog
{
...
BOOL m_bLDown;
CPoint m_oldPoint;
CRect m_oldRect;
HCURSOR m_hCursWE;
};
BOOL CMyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
¡­
[/Quote]

我想,这个窗体至少还能响应鼠标移动的消息吧。
没办法,既然如此,只好用回之前考虑的方法了,代码量差不多的,


1. 搭配WM_MOUSEMOVE, WM_LBUTTONDOWN+ WM_lBUTTONUP;
2. SetCapture() + ReleaseCapture();
3. 自己计算是否到达窗体的边缘,以获取相对于屏幕坐标为主。
gauldoth 2009-08-06
  • 打赏
  • 举报
回复
必须用这种方法实现么?
有没有其他的办法能在透明的窗体上放控件?
最近也在做这个,也是遇到相同问题..
UpdateLayeredWindow后就啥都没了..
能否把窗体上控件全部手动重画一遍?
cadhy 2009-08-05
  • 打赏
  • 举报
回复

牛,很牛
lwykj 2009-08-05
  • 打赏
  • 举报
回复
不错!
jameshooo 2009-08-05
  • 打赏
  • 举报
回复
响应WM_NCHITTEST消息即可实现拉伸
加载更多回复(16)
欢迎来到《绿幕虚拟演播技术》课程!这个课程将向您展示如何使用先进的虚拟演播技术,创造出高质量的直播、短视频和其他数字导演作品。我们的课程将引导您掌握绿幕演播技术的原理和技术要点,以及如何搭建一个稳定的开发框架。此外,在本课程的学习过程中,您将了解到,所学开发技术不仅可以服务于中央、省、市、县各级电视台,可以直接服务于全网1.4亿广大个人主播的消费群体!该技术服务于包括抖*、快*、视*号、B*、小*书等广大平台的主播朋友,相信通过本课程将给您带来高质量的学习体验。本课程的巨大价值:A: 如果你是3-10年Unity开发经验老手。     本课程可以协助你快速搭建虚拟演播框架,进一步丰富功能,为您公司的电视台、大型影视工作机构的客户提供虚拟演播技术服务。B: 如果你是0-3年的Unity初学者。     本课程的学习可以协助你进一步丰富与掌握Unity知识体系。掌握虚拟演播技术,开发服务于个人主播的特效与演播软件,通过抖*,快*等平台,直接通过直播方式,售卖自己的演播软件,自己的个人创业梦想!C: 如果你是没有任何技术的个人。     您可以通过本课程的最终发布软件包,通过网搜与制作素材结合自己的独特创意,自己运营类似抖* 平台的 “慧慧周” 等优质特效账号,个人造福梦想!本课程大纲包括:1. 绿幕虚拟演播技术的应用与前景介绍;2. 绿幕虚拟演播技术的原理和技术要点;3. 搭建绿幕虚拟演播技术开发框架;4.绿幕虚拟演播软件的功能使用与快速出视频要点,包括如何优化绿幕技术、如何管理实际数据源,以及如何应对不同场景的挑战。我们相信,通过本门课程的学习,您将成为一名精通绿幕虚拟演播技术的行业专业人才。作为业内领先的实践者,所需工作将越来越多。走在时代前沿,和亿万主播一道成为数字时代的推手!快快报名吧!

15,978

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧