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一些经验系列:《平均绘画矩形图,双击全屏》的更多相关文章

  1. VC一些经验系列: 《分享泄漏检测工具:内存、DC、GDI、Handle... 》

    分享下自己工作中用到的一些用于泄漏检测的工具 后面的是DC的一些定义和注意事项.(不喜勿看) //=================================================== ...

  2. android 内存泄漏检测工具 LeakCanary 泄漏金丝雀

    韩梦飞沙 yue31313 韩亚飞 han_meng_fei_sha 313134555@qq.com 内存泄漏检测工具 android 内存泄漏检测工具 ======== 内存泄漏 就是  无用的对 ...

  3. Cocos开发中性能优化工具介绍之Visual Studio内存泄漏检测工具——Visual Leak Detector

    那么在Windows下有什么好的内存泄漏检测工具呢?微软提供Visual Studio开发工具本身没有什么太好的内存泄漏检测功能,我们可以使用第三方工具Visual Leak Detector(以下简 ...

  4. C++内存泄漏检测工具

    C++内存泄漏检测工具 1.VC自带的CRT:_CrtCheckMemory   调试器和 CRT 调试堆函数 1.1用法: /************************************ ...

  5. C/C++的内存泄漏检测工具Valgrind memcheck的使用经历

    Linux下的Valgrind真是利器啊(不知道Valgrind的请自觉查看参考文献(1)(2)),帮我找出了不少C++中的内存管理错误,前一阵子还在纠结为什么VS 2013下运行良好的程序到了Lin ...

  6. Android 性能优化之内存泄漏检测以及内存优化(中)

    https://blog.csdn.net/self_study/article/details/66969064 上篇博客我们写到了 Java/Android 内存的分配以及相关 GC 的详细分析, ...

  7. 内存泄漏检测工具VLD在VS2010中的使用举例

    Visual LeakDetector(VLD)是一款用于Visual C++的免费的内存泄露检测工具.它的特点有:(1).它是免费开源的,采用LGPL协议:(2).它可以得到内存泄露点的调用堆栈,可 ...

  8. 内存泄漏检测工具Valgrind

    1概述 1.1 介绍 Valgrind是一套Linux下,开放源代码(GPL V2)的仿真调试工具的集合.Valgrind由内核(core)以及基于内核的其他调试工具组成.内核类似于一个框架(fram ...

  9. Cocos性能优化工具的开发介绍Visual Studio内存泄漏检测工具——Visual Leak Detector

    然后,Windows下有什么好的内存泄漏检測工具呢?微软提供Visual Studio开发工具本身没有什么太好的内存泄漏检測功能.我们能够使用第三方工具Visual Leak Detector(下面简 ...

  10. 【转】Unix下C程序内存泄漏检测工具Valgrind安装与使用

    Valgrind是一款用于内存调试.内存泄漏检测以及性能分析的软件开发工具. Valgrind的最初作者是Julian Seward,他于2006年由于在开发Valgrind上的工作获得了第二届Goo ...

随机推荐

  1. hdu 5009 Paint Pearls

    首先把具有相同颜色的点缩成一个点,即数据离散化. 然后使用dp[i]表示涂满前i个点的最小代价.对于第i+1个点,有两种情况: 1)自己单独涂,即dp[i+1] = dp[i] + 1 2)从第k个节 ...

  2. 【仿携程JQuery日期价格表】

    今天比较闲所以就花点时间又写了点东西. 相信这种价格表大家不会陌生 现在我就模仿它做一个简单版本的.效果如下 首先需要两个时间控件,我这里用的是HTML5里面的时间控件,这个没限制喜欢用什么就用什么 ...

  3. Windows Linux HackMacintosh

    我想把Windows Linux HackMacintosh三类系统融入到一台笔记本上的神经病应该不多. 我的电脑就一个SATA硬盘,BIOS还不是EFI的.一共同时安装了Windows 8.1.Op ...

  4. 【转】循环递归遍历XML文档或按某要求遍历XML文档

    <?xml version="1.0" encoding="UTF-8"?> <catalog> <cd> <titl ...

  5. Cassandra1.2文档学习(2)——节点间通信协议之gossip协议

    参考文档:http://www.datastax.com/documentation/cassandra/1.2/webhelp/index.html#cassandra/architecture/a ...

  6. 恢复Delphi XE2的Library Path

    Delphi XE2好好的,手贱乱删,结果新建一个工程都不能编译了,出现:DELPHI X2 [DCC Fatal Error] KjcxClient.dpr(1): F1027 Unit not f ...

  7. 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 ...

  8. 由12306出错想到的div垂直居中的问题

    今天想看看元旦回家还有没有余票,偷偷的打开了12306,开始查询回家的车票,结果发现,竟然查询不出来,再查直接出错了 看到这个很郁闷,很纠结,但是突然想到了最近一直想实现div垂直居中,赶紧试了一下1 ...

  9. SIAlertView

    SIAlertView是AlertView的替代产品 的效果比较多 . 使用实例: SIAlertView *alertView = [[SIAlertView alloc] initWithTitl ...

  10. Codeforces Round #209 (Div. 2)

    A: 要么是两次要么4次,判断是否在边界: #include<cstdio> using namespace std; int main() { int n,m,x; ; scanf(&q ...