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. java.util.Hashtable源码分析

    Hashtable实现一个键值映射的表.任何非null的object可以用作key和value. 为了能存取对象,放在表里的对象必须实现hashCode和equals方法. 一个Hashtable有两 ...

  2. 通过 ANE(Adobe Native Extension) 启动Andriod服务 推送消息(三)

    jar包完成后,剩下就是要构建ANE包来供实际程序调用. 首先要建两个Flex库项目, default那个是官方建议加上的,仅用于不在真实环境下编译调试的时候有个默认接口不至于调用不成功报错,项目结构 ...

  3. Qt-获取主机网络信息之QHostAddress

    QHostAddress类提供一个IP地址. 这个类提供一种独立于平台和协议的方式来保存IPv4和IPv6地址. QHostAddress通常与QTcpSocket,QTcpServer,QUdpSo ...

  4. Linux C 程序 基础(FOUR)

    1.标识符:C语言本身不限制变量长度,但是某些编译器会限制变量长度,命名最好不要超过8位.         以数字开头,保留字,*,空格非法 2.关键字:类型说明符,int , 语句定义符,if el ...

  5. iOSCoreData介绍

    1.CoreData简介 Coredata用作数据持久化,使和大数据量的存储和查询 虽然是用户做数据的保存,但是并不是数据库,CoreData可以使用数据库.XML来存储数据 SQLite通过SQL语 ...

  6. 计算连续的IP地址

    题目:要求计算连续的IP地址. 举例:起始IP为192.168.2.2,IP总个数为3,那么要求得的所有IP的为192.168.2.2,192.168.2.3,192.168.2.4.再举个例子,起始 ...

  7. power designer

    概述 Power Designer 是Sybase公司的CASE工具集,使用它可以方便地对管理信息系统进行分析设计,他几乎包括了数据库模型设计的全过程.利用Power Designer可以制作数据流程 ...

  8. mui 重写back 调用back方法,实现返回就即时刷新页面

    需求: 从A-----b页面  B操作完后再返回A ,这时A页面数据变化 1.先是针对安卓机可以点击按钮返回,也可以用本机的返回键返回 监听本机的返回按钮,如果点击就调用写好的自定义刷新事件 (fun ...

  9. php实现单链表

    <?php /** * 单链表 */ class Demo { private $id; public $name; public $next; public function __constr ...

  10. java学习--抽象类与接口

    一.抽象 在使用抽象类时需要注意几点: 1.抽象类不能被实例化,实例化的工作应该交由它的子类来完成,它只需要有一个引用即可. 2.抽象方法必须由子类来进行重写. 3.只要包含一个抽象方法的抽象类,该方 ...