VC一些经验系列:《平均绘画矩形图,双击全屏》
1.RGB宏报错
RGB宏是这样的,
#define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))
但是penBlack.CreatePen(PS_SOLID, 3, #ff0000); 在有的文件中可以用,有的文件中会报错【error C2064: 项不会计算为接受 1 个参数的函数】
我猜应该是编译器,包含的括号运算有一定的限制导致的。
所以改成((COLORREF)(((255)|((WORD)((0))<<8))|(((DWORD)(0))<<16))); //(BYTE) 删除就可以了
//draw rectangle
dc.SelectStockObject(NULL_BRUSH); //不使用画刷
CPen penBlack;
//penBlack.CreatePen(PS_SOLID, 3, #ff0000);
COLORREF crColor = ((COLORREF)(((255)|((WORD)((0))<<8))|(((DWORD)(0))<<16)));
penBlack.CreatePen(PS_SOLID, 3, crColor);
CPen* pOldPen = dc.SelectObject(&penBlack);
dc.Rectangle(CRect(WndRect.left -2,WndRect.top -2, WndRect.right+1,WndRect.bottom+1));
2. 给出窗口的总数,计算每行要画多少窗口
//计算每行窗口的个数 //1 4 9 16 32 64 128 256
float fMaxWndNumOfRow = sqrt((float)nNumOfLVWnd);
long nTemp = fMaxWndNumOfRow;
int nMaxWndNumOfRow = fMaxWndNumOfRow>nTemp?nTemp+1:nTemp;
3. 得到每行的窗口数量之后,就可以按照比例 1*1 , 2*2, 3*3, 4*4, 5*5, 6*6,来画图了
void CMainDialog::DeployLiveViewWnds(int nNumOfLVWnd) //just Comment关于画图,最好用float---doubel 因为更精确
{OutputDebugString(L"enter DeployLiveViewWnds"); this->Invalidate();//reflash windows first nTotalWnd = nNumOfLVWnd; //计算每行窗口的个数 //1 4 9 16 32 64 128 256
float fMaxWndNumOfRow = sqrt((float)nNumOfLVWnd);
long nTemp = fMaxWndNumOfRow;
int nMaxWndNumOfRow = fMaxWndNumOfRow>nTemp?nTemp+:nTemp; int i(), nRow(), nCol(), nTempNumOfLVWnd();
int nLVWndWidth(), nLVWndHeight();
int nNextX(), nNextY(), nNextWidth(), nNextHeight();
CRect rectClient;
this->GetClientRect(rectClient); //==============
//just 位移 让 右 和 下 都有足够的位置画完矩形,普通场合 右和下 会少一个像素
rectClient.bottom = rectClient.bottom -;
rectClient.right = rectClient.right -;
//============== // Get the width and height of live view window
TCHAR temp[];
wsprintf(temp, L"CMainDialog::DeployLiveViewWnds () 主窗口 left=%d, top=%d, right=%d, bottom=%d , ",rectClient.left, rectClient.top, rectClient.right, rectClient.bottom);
OutputDebugString(temp); //bottom = 600
//right = 800 //1280 720
//640-1 310-1 //800* 600
//400-1*300-1
//if 1windows 0, 0, 400-1, 300-1
//if 2windows 400, 0, 400-1, 300-1
//if 3windows 0, 300, 400-1, 300-1
//if 4windows 400, 300, 400-1, 300-1 nLVWndWidth = (rectClient.right - PPT_LEFT_CTRL_PANEL_WIDTH - ) / nMaxWndNumOfRow; //(800 -0 -1) /2 = 399
if (nNumOfLVWnd % nMaxWndNumOfRow == )
{
nTempNumOfLVWnd = nNumOfLVWnd;
wsprintf(temp,L"nNumOfLVWnd = %d",nNumOfLVWnd);
OutputDebugString(temp);
//4 windows //4%2 = 0 => nTempNumOfLVWnd = 4
}
else
nTempNumOfLVWnd = nNumOfLVWnd + nMaxWndNumOfRow - (nNumOfLVWnd % nMaxWndNumOfRow);
//1 windows //1+2 -(1%2) = 2
//9 windows //9+3 -(9%3) = 3 wsprintf(temp,L"hejie rectClient.bottom=%d, nTempNumOfLVWnd=%d",rectClient.bottom,nTempNumOfLVWnd);
OutputDebugString(temp); nLVWndHeight = (rectClient.bottom - PPT_BOTTOM_CTRL_PANEL_HEIGHT - ) / (nTempNumOfLVWnd / nMaxWndNumOfRow);
// (600-0-1)/ (2/2) => 599
// (600-0-1)/ (2/2) => 599
// (600-0-1)/ (4/2) => 299
// (600-0-1)/ (4/2) => 299
// (600-0-1)/ (9/3) => 199.6 wsprintf(temp,L"hejie nLVWndHeight=%d",nLVWndHeight);
OutputDebugString(temp); OutputDebugString(L"Deploy the windows of live view========");
// Deploy the windows of live view
for (i = ; i < MAX_LIVE_VIEW_WINDOWS; i++)
{
if (i < nNumOfLVWnd) { OutputDebugString(L"before InvalidateRect");
m_pLVWnd[i]->InvalidateRect(NULL, FALSE);//redraw the rectangle
nRow = i / nMaxWndNumOfRow; //0++ / 2 => 0 0.5 1 1.5
nCol = i % nMaxWndNumOfRow; //0++ % 2 => 0 1 0 0
// Calculate the coordinates and size for each live view window
nNextX = PPT_LEFT_CTRL_PANEL_WIDTH + (nCol * nLVWndWidth) + ;
nNextY = (nRow * nLVWndHeight) + ; wsprintf(temp,L"hejie nNextX=%d, nNextY=%d================",nNextX,nNextY);
OutputDebugString(temp); if (rectClient.right - (nNextX + nLVWndWidth) < nLVWndWidth)
nNextWidth = rectClient.right - nNextX - ;
else
nNextWidth = nLVWndWidth;
if ((rectClient.bottom - PPT_BOTTOM_CTRL_PANEL_HEIGHT) - (nNextY + nLVWndHeight) < nLVWndHeight)
nNextHeight = (rectClient.bottom - PPT_BOTTOM_CTRL_PANEL_HEIGHT) - nNextY - ;
else
nNextHeight = nLVWndHeight; wsprintf(temp,L"moveWindows 第%d个子窗口 的 nNextX=%d, nNextY=%d, nNextWidth=%d, nNextHeight=%d ",i,nNextX,nNextY,nNextWidth,nNextHeight);
OutputDebugString(temp); //让LiveViewWnd窗口小一点, 每个窗口中间的分隔大一点。offset值-2为了缩放窗口, 让给显示选中矩形框
m_pLVWnd[i]->MoveLVWindow(nNextX +, nNextY +, nNextWidth -, nNextHeight-);//modify the windwos Count!!!!!important 设置默认小窗口的size
m_pLVWnd[i]->ShowWindow(SW_SHOW); //保留每个liveView Wnd的rect
if(LV_WND_4 == nTotalWnd )
{
SubLiveViewRect4[i] = CRect( nNextX +, nNextY+, nNextWidth + nNextX+, nNextHeight + nNextY+); //left和top + 1是因为不和LiveView重合
//right 和bottom +2 是因为 前面offset已经+1了,然后需要再+1么?
}
else if(LV_WND_9 == nTotalWnd )
{
/*
#ifdef _AFX_NO_OCC_SUPPORT
_AFXWIN_INLINE void CWnd::MoveWindow(int x, int y, int nWidth, int nHeight, BOOL bRepaint)
{ ASSERT(::IsWindow(m_hWnd)); ::MoveWindow(m_hWnd, x, y, nWidth, nHeight, bRepaint); }
#endif //_AFX_NO_OCC_SUPPORT
_AFXWIN_INLINE void CWnd::MoveWindow(LPCRECT lpRect, BOOL bRepaint)
{ MoveWindow(lpRect->left, lpRect->top, lpRect->right - lpRect->left,
lpRect->bottom - lpRect->top, bRepaint); }
*/
//我们可以知道x,y, nWidth,nHeight 如何通过rect得到,
//lpRect->left, lpRect->top,
//lpRect->right - lpRect->left, //3-1
//lpRect->bottom - lpRect->top, //4-2
//上面是MoveWinodws()的X,Y,Width,Height 值。 请看上面是MoveWindows()的定义 //反过来,要换算成rect值,
//只需要nNextX , nNextY, nNextHeight + nNextX, nNextWidth + nNextY SubLiveViewRect9[i] = CRect( nNextX + , nNextY +, nNextWidth + nNextX+ , nNextHeight + nNextY+ ); } }
else {
m_pLVWnd[i]->InvalidateRect(NULL, FALSE);
m_pLVWnd[i]->ShowWindow(SW_HIDE);
}
}
}
平均分隔多个窗口
重点是:MoveWindow(x,y, width, height)要换算成Rect矩形,废了蛮多周折,才找到原因。 所以才会想起写下此篇文章。
我们的需求是这样的,
平均分隔各个视图后,
用户单击/双击 后,需要有选中矩形(单击/双击 选中后,可以操作此视图对象+数据对象; 双击 全屏放大 )
刷新如何不让丢失呢?在mainDialog的OnPaint()中,先判断nChooseIndex的值,这个值在subView中的单机事件中得到。
然后根据我们分隔画面的保存 CRect[i]来保存每个SubView的Rectangle,
然后就可在OnPaint()中画选中的矩形了
void CMainDialog::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CDialog::OnPaint() //选中矩形,若单窗口模式下,则不画选中矩形
if ( nTotalWnd != )
{
//draw rectangle
dc.SelectStockObject(NULL_BRUSH); //不使用画刷
CPen penBlack;
COLORREF crColor = ((COLORREF)((()|((WORD)(())<<))|(((DWORD)())<<)));
penBlack.CreatePen(PS_SOLID, , crColor);//penBlack.CreatePen(PS_SOLID, 3, #ff0000);
CPen* pOldPen = dc.SelectObject(&penBlack); if (LV_WND_4 == nTotalWnd)
{
dc.Rectangle(&SubLiveViewRect4[nChooseWnd]);
} if (LV_WND_9 == nTotalWnd)
{
dc.Rectangle(&SubLiveViewRect9[nChooseWnd]);
} }
}
OnPaint
4、画矩形还有很多种方法
//方法1. 实心矩形,和第4个方法是一样的,一个是实心,一个是空心
CPen penBlack;
penBlack.CreatePen(PS_TYPE_MASK, 3, #0000ff);
m_pDC->SelectObject(&penBlack);
m_pDC->Rectangle(&WndRect);
penBlack.DeleteObject();
//方法2.直接画线段,可以设置线的粗细,颜色 ,这个最好,但是麻烦点。
CPen penBlack;
penBlack.CreatePen(PS_SOLID, 3, #000000);
m_pDC->SelectObject(&penBlack);
m_pDC->MoveTo(WndRect.left -3, WndRect.top);
m_pDC->LineTo(WndRect.left -3, WndRect.bottom -3 );
m_pDC->LineTo(WndRect.right , WndRect.bottom );
m_pDC->LineTo(WndRect.right , WndRect.top );
m_pDC->LineTo(WndRect.left -3, WndRect.top -3 );
penBlack.DeleteObject();
//方法3 . 空心,但是没有办法设置线的粗细
CBrush brushBlue(#000000);
dc.FrameRect(&WndRect,&brushBlue);
//方法4 . 空心,可设置线的粗细,颜色
CClientDC dc(this); //获取设备句柄
dc.SelectStockObject(NULL_BRUSH); //不使用画刷
CPen penBlack;
penBlack.CreatePen(PS_SOLID, 3, #ff0000);
CPen* pOldPen = dc.SelectObject(&penBlack);
//pOldPen->DeleteObject(); //大家可以试下DeleteObject penBlack和pOldPen 有什么区别
//dc.Rectangle(CRect(WndRect.left -2,WndRect.top -2, WndRect.right+1,WndRect.bottom+1));
//方法5 不能设置线的粗细,d3d不懂,如果错了,欢迎大家纠正,共同提高嘛, 不过朋友叫我速度学openGL ,他们那做游戏,如果想赚点钱,可以试试吧。
//pDC->Draw3dRect(&WndRect,#ff0000,#00ff00);
5.双击全屏,再双击还原
我试过很多方法,最简单的就是MoveWindows,但是全屏后能还原小窗口的都不满意,
我就介绍一种完美的解决方案吧。
void CLiveViewWnd::OnLButtonDblClk(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CMainDialog* mainDialog = NULL;
mainDialog = (CMainDialog*) GetParent();
mainDialog->nChooseWnd = m_ucWndNo; CStatic::OnLButtonDblClk(nFlags, point);
OutputDebugString(L"enter =====================CLiveViewWnd::OnLButtonDblClk"); m_bFullScreen=!m_bFullScreen; // 设置全屏显示标志
LONG style = ::GetWindowLong(this->m_hWnd,GWL_STYLE); if(m_bFullScreen)//全屏显示
{
/* //用MFC隐藏系统任务栏
CWnd * wnd = FindWindow(L"Shell_TrayWnd",NULL);
wnd->SetWindowPos(NULL,0,0,0,0,SWP_HIDEWINDOW);
*/ m_hWndParent=::GetParent(m_hWnd);
::ShowWindow(m_hWndParent,SW_HIDE); ::SetParent(m_hWnd,NULL);
style &= ~(WS_DLGFRAME | WS_THICKFRAME); SetWindowLong(this->m_hWnd,NULL, style);//SetWindowLong(this->m_hWnd,GWL_STYLE, style); GWL_STYLE表示MFC窗口属性,NULL表示没有窗口属性。
this->ShowWindow(SW_SHOWMAXIMIZED);//this->ShowWindow(SHOW_FULLSCREEN); //CRect rect;
//this->GetWindowRect(&rect);
//::SetWindowPos((this->m_hWnd,HWND_NOTOPMOST,rect.left-1, rect.top-1, rect.right-rect.left + 3, rect.bottom-rect.top + 3, SWP_FRAMECHANGED); int nScreenWidth=GetSystemMetrics(SM_CXSCREEN);
int nScreenHeight=GetSystemMetrics(SM_CYSCREEN);
::SetWindowPos(this->m_hWnd,HWND_TOPMOST,,, nScreenWidth,nScreenHeight, SWP_FRAMECHANGED);
}
else
{
/* //用MFC显示系统任务栏
CWnd * wnd = FindWindow(L"Shell_TrayWnd",NULL);
wnd->SetWindowPos(NULL,0,0,0,0,SWP_SHOWWINDOW);
//this->SetWindowPos(NULL,0,0,0,0,SWP_SHOWWINDOW);
*/ style |= WS_DLGFRAME | WS_THICKFRAME;
SetWindowLong(this->m_hWnd, NULL, style);
::SetParent(m_hWnd,m_hWndParent);
::ShowWindow(m_hWndParent,SW_SHOW);
}
}
OnLButtonDblClk
需要注意的是
SetWindowLong(this->m_hWnd,GWL_STYLE, style); // GWL_STYLE表示MFC窗口属性,NULL表示没有窗口属性。
SetWindowPos(this->m_hWnd,HWND_TOPMOST,0,0, nScreenWidth,nScreenHeight, SWP_FRAMECHANGED); //HWND_TOPMOST 显示优先级为最高层
VC一些经验系列:《平均绘画矩形图,双击全屏》的更多相关文章
- VC一些经验系列: 《分享泄漏检测工具:内存、DC、GDI、Handle... 》
分享下自己工作中用到的一些用于泄漏检测的工具 后面的是DC的一些定义和注意事项.(不喜勿看) //=================================================== ...
- android 内存泄漏检测工具 LeakCanary 泄漏金丝雀
韩梦飞沙 yue31313 韩亚飞 han_meng_fei_sha 313134555@qq.com 内存泄漏检测工具 android 内存泄漏检测工具 ======== 内存泄漏 就是 无用的对 ...
- Cocos开发中性能优化工具介绍之Visual Studio内存泄漏检测工具——Visual Leak Detector
那么在Windows下有什么好的内存泄漏检测工具呢?微软提供Visual Studio开发工具本身没有什么太好的内存泄漏检测功能,我们可以使用第三方工具Visual Leak Detector(以下简 ...
- C++内存泄漏检测工具
C++内存泄漏检测工具 1.VC自带的CRT:_CrtCheckMemory 调试器和 CRT 调试堆函数 1.1用法: /************************************ ...
- C/C++的内存泄漏检测工具Valgrind memcheck的使用经历
Linux下的Valgrind真是利器啊(不知道Valgrind的请自觉查看参考文献(1)(2)),帮我找出了不少C++中的内存管理错误,前一阵子还在纠结为什么VS 2013下运行良好的程序到了Lin ...
- Android 性能优化之内存泄漏检测以及内存优化(中)
https://blog.csdn.net/self_study/article/details/66969064 上篇博客我们写到了 Java/Android 内存的分配以及相关 GC 的详细分析, ...
- 内存泄漏检测工具VLD在VS2010中的使用举例
Visual LeakDetector(VLD)是一款用于Visual C++的免费的内存泄露检测工具.它的特点有:(1).它是免费开源的,采用LGPL协议:(2).它可以得到内存泄露点的调用堆栈,可 ...
- 内存泄漏检测工具Valgrind
1概述 1.1 介绍 Valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合.Valgrind由内核(core)以及基于内核的其他调试工具组成.内核类似于一个框架(fram ...
- Cocos性能优化工具的开发介绍Visual Studio内存泄漏检测工具——Visual Leak Detector
然后,Windows下有什么好的内存泄漏检測工具呢?微软提供Visual Studio开发工具本身没有什么太好的内存泄漏检測功能.我们能够使用第三方工具Visual Leak Detector(下面简 ...
- 【转】Unix下C程序内存泄漏检测工具Valgrind安装与使用
Valgrind是一款用于内存调试.内存泄漏检测以及性能分析的软件开发工具. Valgrind的最初作者是Julian Seward,他于2006年由于在开发Valgrind上的工作获得了第二届Goo ...
随机推荐
- hdu 5009 Paint Pearls
首先把具有相同颜色的点缩成一个点,即数据离散化. 然后使用dp[i]表示涂满前i个点的最小代价.对于第i+1个点,有两种情况: 1)自己单独涂,即dp[i+1] = dp[i] + 1 2)从第k个节 ...
- 【仿携程JQuery日期价格表】
今天比较闲所以就花点时间又写了点东西. 相信这种价格表大家不会陌生 现在我就模仿它做一个简单版本的.效果如下 首先需要两个时间控件,我这里用的是HTML5里面的时间控件,这个没限制喜欢用什么就用什么 ...
- Windows Linux HackMacintosh
我想把Windows Linux HackMacintosh三类系统融入到一台笔记本上的神经病应该不多. 我的电脑就一个SATA硬盘,BIOS还不是EFI的.一共同时安装了Windows 8.1.Op ...
- 【转】循环递归遍历XML文档或按某要求遍历XML文档
<?xml version="1.0" encoding="UTF-8"?> <catalog> <cd> <titl ...
- Cassandra1.2文档学习(2)——节点间通信协议之gossip协议
参考文档:http://www.datastax.com/documentation/cassandra/1.2/webhelp/index.html#cassandra/architecture/a ...
- 恢复Delphi XE2的Library Path
Delphi XE2好好的,手贱乱删,结果新建一个工程都不能编译了,出现:DELPHI X2 [DCC Fatal Error] KjcxClient.dpr(1): F1027 Unit not f ...
- python参考手册 Read
P28 复制 a = [1,2,3,[1,2]] b = a b is a # True c = list[a] # shallow copy c is a # False c[3][0] = 100 ...
- 由12306出错想到的div垂直居中的问题
今天想看看元旦回家还有没有余票,偷偷的打开了12306,开始查询回家的车票,结果发现,竟然查询不出来,再查直接出错了 看到这个很郁闷,很纠结,但是突然想到了最近一直想实现div垂直居中,赶紧试了一下1 ...
- SIAlertView
SIAlertView是AlertView的替代产品 的效果比较多 . 使用实例: SIAlertView *alertView = [[SIAlertView alloc] initWithTitl ...
- Codeforces Round #209 (Div. 2)
A: 要么是两次要么4次,判断是否在边界: #include<cstdio> using namespace std; int main() { int n,m,x; ; scanf(&q ...