双缓冲故障(使用小型演示源代码更新) [英] Double buffering malfunctions (updated with small demo source code )

查看:105
本文介绍了双缓冲故障(使用小型演示源代码更新)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

介绍和相关信息:



我在主窗口中有一个复杂的绘画 WM_PAINT 处理程序。



我已经提交了一张图片来说明它:

< a href =http://pbrd.co/18fNYYp> http://pbrd.co/18fNYYp [ ^ ]



主窗口有静态控件,而不是按钮,其样式为 SS_NOTIFY

当用户点击它们时,某些操作会在程序中发生,这与现在无关。



以下图片显示主窗口中静态控件的位置:

http://pbrd.co/18fOkya [< a href =http://pbrd.co/18fOkyatarget =_ blanktitle =New Window> ^ ]



地图上橙色面板是 EMF 文件,左上角和右上角徽标是 PNG 文件,以及其他图片ures是位图 s。



视觉样式是通过 #pragma 指令启用。我还使用 GDI + 以及 GDI



项目是作为空项目创建的,我已经从临时编码了所有内容。



为了实现这个任务,我决定绘制整个图片 WM_PAINT ,以及对图片上的图像放置透明静态控件。



为了保持我的代码干净简单,我已经制作了实现上述功能的函数,所以我的 WM_PAINT 处理程序可以很小尽可能。



使用 GradientFill(...) API制作渐变画笔。 />


我在 Windows XP 上工作,使用 MS Visual Studio C ++ 2008 Express Edition Win32 API



一个音符:由于VS 的Express版本没有资源编辑器,因此创建了资源文件和资源头g ResEdit 从这里开始:

http://www.resedit.net/。 [ ^ ]



更新#1(2013年12月17日更新) ):



为了让那些试图帮助的人更容易,这里是一个包含最少代码的单一源文件问题: http://pastebin.com/BeAVHViC [ ^ ]



问题:



为了避免闪烁,我使用了双缓冲,我从 Paul Watt 的文章中了解到, Charles Petzold的编程Windows第5版 Forger的WIN32教程



从理论上讲,一切正常,我的代码编译没有任何错误。



我在这里粘贴了代码:

http:// pastebin.com/zSYT1i8L [ ^ ]



我的英语不够准确无法准确描述我所面临的问题(我只能说主窗口的边缘和静态控件重绘慢并且它们闪烁)所以我创建了一个演示应用程序来演示它们:

http://www.filedropper.com/geotermistgrafika [ ^ ]



我努力解决问题:



我已处理 WM_ERASEBKGND (已退回(LRESULT)1 ),我已经从我的窗口类中排除了 CS_VREDRAW CS_HREDRAW 的样式 - 因此不应该因此导致闪烁。



我的窗口没有 WS_CLIPCHILDREN 样式,因为部分桌面图片在哪里静态控件是。



在我的 WM_SIZE 处理程序中我有:

1。 使用 SetWindowPos(...) API重新定位静态控件,并通过添加 SWP_NOCOPYBITS 标志减少闪烁。



2. 使用 InvalidateRect(hWnd,NULL,FALSE),所以这个API在无效时发送 WM_ERASEBKGND (第三个参数是 FALSE ),但即使我尝试使用 TRUE 效果相同。



我已经为 WM_PAINT 处理程序实现了双缓冲,就像上面的书/文章/教程中的示例一样(通过在内存DC中执行所有操作并在屏幕DC上执行 BitBlt(...)以避免闪烁)。



我没有处理 WM_SIZING ,也没有 WM_WINDOWPOSCHANGING WM_MOVING 消息。



我使用了工具 GDIView http://www.nirsoft.net/utils/gdi_handles.html [ ^ ])追踪 GDI泄漏

每次我调整大小/最大化我的窗口, GDIView 在区域列中显示+4,这应该意味着我泄漏了区域,但我无法弄清楚这是如何可能的,因为我不使用操纵的API地区,并仔细检查了一切。



在我看来,一切都应该没问题,也许这是无关紧要的,但我只是想提一下,万一它很重要。



如果我在主窗口中添加 WS_EX_COMPOSITED 样式,性能不会提高。



我试图找到帮助我解决问题的在线示例,但所有教程都很简单,不包括这类复杂的图片。



重要提示:



在改进这个问题之前,我提出了两个解决方案,其中一个建议我做同样的事情因为我可以在 WM_ERASEBKGND



离开我的 WM_PAINT 处理程序为空并调用 onPaint 函数在 WM_ERASEBKGND 中,使用 GetDC(..) API获取设备上下文,闪烁消失,但在调整大小,重新绘制窗口是尖刻的,主窗口边缘的问题没有解决。

仍然,这比原始代码好得多。



更新(2013年12月17日):



删除后从 onPaint 调用 drawImages(hdc,MemDC,r); ,再次出现边缘闪烁。 />


似乎更少了,区域数 GDIView 检测到泄漏减少了一个



问题:



如何摆脱上面提供的演示应用程序中演示的问题?



我特此感谢任何投入时间和精力去帮助我的人。



祝你好运。

解决方案

CPallini是绝对正确的。使用WM_PAINT或OnPaint方法绘画会导致闪烁。使用WM_ERASEBKGND消息绘制大部分内容。



阅读一些关于为初学者绘画的文章。关键是要避免重绘。



http://www.codeproject.com/search.aspx?q=paint+for+beginners&x=-1262&y=-146&sbo=kw [ ^ ]



我通过迭代解决了这些问题:只绘制一块,如果有效,我将激活下一个只要它工作...



提示:不使用控件,但检查鼠标坐标并通过向窗口发送消息来处理它。


这是我用它做的。我离开了drawImages函数供你重写。

你应该可以使用CBitmap和CBitmap *而不会破坏你的代码。



< pre lang =c ++> #include resource.h
#include < windows.h >
#include < < span class =code-leadattribute> afxwin.h >
#include < windowsx.h < span class =code-keyword>> // for TransparentBlt()
#include < commctrl.h >
#include < gdiplus.h >
#pragma comment(linker,/ manifestdependency:\type ='win32'\
name = ' Microsoft.Windows.Common-Controls' version = ' 6.0.0.0' \
processorArchitecture = ' *' publicKeyToken = ' 6595b64144ccf1df' \
language = ' *' \
#pragma comment(lib,comctl32.lib)
#pragma comment(lib,Msimg32.lib)// for TransparentBlt()
#pragma comment(lib,Gdiplus.lib)
使用 命名空间 Gdiplus;
// 用于存储实例的变量
静态 HINSTANCE hInst;
// 图标
静态 HICON hIcon, // 主窗口的图标
hiAdmin; // 状态栏左下角的图标
// 徽标图片
图片*图片, // 主窗口顶部横幅上的左侧徽标
* image1, // 主窗口顶部横幅上的右侧徽标
* btn5; // 橙色静态控件的地图
// 绘制窗口的变量

静态 HBRUSH hbPozadina , // 网格顶部的灰色背景画笔
BlueFrame, // 构建蓝色静态控件所需
hbr; // 橙色面板的橙色笔刷

静态 HBITMAP bmpBTN1, // 左上角蓝色静态控件的图像
bmpBTN2, // 右上角蓝色静态控制的图像
// ============这两个制作一个图像=========== / /
bmpBTN3, // 左下角蓝色静态控件的左图
bmpBTN3a, // 左下方蓝色静态控制的右图
// =========================== ======================= //
bmpBTN4, // 右下角蓝色静态控件的图像
bmpSimbol, // 主窗口顶部横幅上的中间徽标
bmpInfo, // 第一个橙色静态控件的子窗口的左上角图像
bmpLink, // 第3个橙色静态控件的子窗口左上角图像
bmpHelp; // 第二个橙色静态控件的子窗口的左上角图像
/ * **************************** * WM_PAINT的辅助函数************************** /
// 使用渐变画笔填充三角形
void GradientTriangle(CDC * MemDC, LONG x1,LONG y1,LONG x2,LONG y2,LONG x3,LONG y3,
COLORREF top,COLORREF bottom)
{
TRIVERTEX vertex [ 3 ];
vertex [ 0 ]。x = x1;
vertex [ 0 ]。y = y1;
vertex [ 0 ]。Red = GetRValue(bottom)<< 8 ;
vertex [ 0 ]。格林= GetGValue(底部)<< 8 ;
vertex [ 0 ]。蓝色= GetBValue(底部)<< 8 ;
vertex [ 0 ]。Alpha = 0x0000;
vertex [ 1 ]。x = x2;
vertex [ 1 ]。y = y2;
vertex [ 1 ]。红色= GetRValue(顶部)<< 8 ;
vertex [ 1 ]。格林= GetGValue(顶部)<< 8 ;
vertex [ 1 ]。蓝色= GetBValue(顶部)<< 8 ;
vertex [ 1 ]。Alpha = 0x0000;
vertex [ 2 ]。x = x3;
vertex [ 2 ]。y = y3;
vertex [ 2 ]。Red = GetRValue(bottom)<< 8 ;
vertex [ 2 ]。格林= GetGValue(底部)<< 8 ;
vertex [ 2 ]。蓝色= GetBValue(底部)<< 8 ;
vertex [ 2 ]。Alpha = 0x0000;
// 创建一个
// 引用TRIVERTEX顶点。
GRADIENT_TRIANGLE gTriangle;
gTriangle.Vertex1 = 0 ;
gTriangle.Vertex2 = 1 ;
gTriangle.Vertex3 = 2 ;
// 绘制阴影三角形。
GradientFill(MemDC,vertex,< span class =code-digit> 3
,& gTriangle, 1 ,GRADIENT_FILL_TRIANGLE);
}
// 绘制页眉和页脚之间窗口部分的背景
void drawBackground(HDC MemDC,RECT r)
{
/ * *******************主窗口的渐变背景************* ** /
GradientTriangle(MemDC,r.right,r.bottom - r.top - 30 ,r.left,r.bottom - r.top - 30
r.left,r.top + 120 ,RGB (0x95,0xB3,0xD7),RGB(0xDB,0xE5,0xF1));
GradientTriangle(MemDC,r.right,r.bottom - r.top - 30 ,r.right,r.top + 120
r.left,r.top + 120 ,RGB(0x95,0xB3,0xD7),RGB(0xDB ,0xE5,0xF1));
}

// 绘制主窗口的标题
void drawHeader(CDC * MemDC,RECT rect,HBRUSH hbPozadina)
{
FillRect(MemDC,& rect,hbPozadina) ; // 在横幅背景上绘制网格
LOGBRUSH lbPozadina;
HGDIOBJ hPenPozadina = NULL,hOldPenPozadina;
lbPozadina.lbColor = RGB( 216 216 216 );
lbPozadina.lbHatch = 0 ;
lbPozadina.lbStyle = BS_SOLID;
hPenPozadina = ExtCreatePen(PS_COSMETIC | PS_SOLID, 1 ,& lbPozadina, 0 ,NULL) ;
hOldPenPozadina = SelectObject(MemDC,hPenPozadina); // 清理所需
for int i = rect.left + 12 ; i< rect.right; i + = < span class =code-digit> 12 )
{
MoveToEx(MemDC,i,rect.top,NULL);
LineTo(MemDC,i,rect.bottom - rect.top + 1 );
}

for int i = rect.top + 12 ; i< rect.bottom; i + = 12
{
MoveToEx(MemDC,rect.left,i,NULL);
LineTo(MemDC,rect.right - rect.left + 1 ,i);
}
// 执行正确的清理
SelectObject(MemDC, hOldPenPozadina);
DeleteObject(hPenPozadina);
/ * ********在顶部横幅底部画一条线** **** /
LOGBRUSH lb;
HGDIOBJ hPen = NULL,hOldPen;
lb.lbColor = RGB( 0 0 0 );
lb.lbHatch = 0 ;
lb.lbStyle = BS_SOLID;
hPen = ExtCreatePen(PS_COSMETIC | PS_SOLID, 1 ,& lb, 0 ,NULL) ;
hOldPen = SelectObject(MemDC,hPen); // 正确清理所需
MoveToEx(MemDC,rect.left,rect.top + 120 ,NULL);
LineTo(MemDC,rect.right - rect.left + 1 ,rect.top + 120 );
// 执行适当的清理
SelectObject(MemDC,hOldPen);
DeleteObject(hPen);
}
// 用渐变画笔填充矩形
void GradientRectangle(CDC * MemDC,LONG x1,LONG y1,LONG x2,LONG y2,COLORREF top,COLORREF bottom)
{
// 静态渐变颜色的顶点
TRIVERTEX vertexS [ 2 < /跨度>];
vertexS [ 0 ]。x = x1;
vertexS [ 0 ]。y = y1;
vertexS [ 0 ]。红色= GetRValue(顶部)<< 8 ;
vertexS [ 0 ]。格林= GetGValue(顶部)<< 8 ;
vertexS [ 0 ]。蓝色= GetBValue(顶部)<< 8 ;
vertexS [ 0 ]。Alpha = 0x0000;
vertexS [ 1 ]。x = x2;
vertexS [ 1 ]。y = y2;
vertexS [ 1 ]。Red = GetRValue(bottom)<< 8 ;
vertexS [ 1 ]。格林= GetGValue(底部)<< 8 ;
vertexS [ 1 ]。蓝色= GetBValue(底部)<< 8 ;
vertexS [ 1 ]。Alpha = 0x0000;
// 创建一个
// 引用TRIVERTEX顶点。
GRADIENT_RECT gRect;
gRect.UpperLeft = 0 ;
gRect.LowerRight = 1 ;
// 绘制阴影矩形。
GradientFill(MemDC,vertexS, 2 ,& gRect, 1 , GRADIENT_FILL_RECT_V);
}
// 用蓝色渐变填充按钮并用蓝色画笔构图
void FillButton(CDC * MemDC,RECT rect,HBRUSH BlueFrame)
{
// 填充矩形的上半部分
GradientRectangle(MemDC,rect.left,rect.top,rect.right,rect .top +(rect.bottom - rect.top)/ 2
RGB(0x95,0xB3,0xD7),RGB(0x4F,0x8B,0xBD) );
// 填充矩形的下半部分
GradientRectangle(MemDC,rect。 left,rect.top +(rect.bottom - rect.top)/ 2
rect.right,rect.bottom,RGB(0x4F,0x8B, 0xBD),RGB(0x95,0xB3,0xD7));
FrameRect(MemDC,& rect,BlueFrame);
}
// 绘制主窗口底部的状态栏
void drawFooter(CDC * MemDC,RECT r,COLORREF top,COLORREF bottom)
{
// 向下三角形
GradientTriangle(MemDC,r.right,r.bottom,(r.right - r。 left)/ 2 ,r.bottom - r.top - 15
r.left ,r.bottom,top,bottom);
// 上三角
GradientTriangle(MemDC,r.right,r。 bottom - r.top - 30 ,(r.right - r.left)/ 2 ,r。 bottom - r.top - 15
r.left,r.bottom - r.top - 30 ,top,bottom);
// 左三角形
GradientTriangle(MemDC,r.left,r。底部,(r.right - r.left)/ 2 ,r.bottom - r.top - 15
r.left,r.bottom - r.top - 30 ,top,bottom);
// 直角三角形
GradientTriangle(MemDC,r.right,r。 bottom - r.top - 30 ,(r.right - r.left)/ 2 ,r。 bottom - r.top - 15
r.right,r.bottom,top,bottom);
// 绘制图标
DrawIconEx(MemDC,r.left,r。 bottom - r.top - 30 ,hiAdmin, 30 30 ,NULL,NULL,DI_NORMAL);
}
// 绘制橙色面板,将绘制地图和3个静态控件
void drawOrangePanel(CDC * MemDC,RECT r,COLORREF top,COLORREF bottom)
{
// 向下三角形
GradientTriangle(MemDC,r.right,r.bottom,r.left +(r。 right - r.left)/ 2 ,r.top +(r.bottom - r.top)/ 2
r.left,r.bottom,top,bottom);
// 上三角
GradientTriangle(MemDC,r.right,r。 top,r.left +(r.right - r.left)/ 2 ,r.top +(r.bottom - r.top)/ 2
r.left,r.top,top,bottom);
// 左三角形
GradientTriangle(MemDC,r.left,r。 bottom,r.left +(r.right - r.left)/ 2 ,r.top +(r.bottom - r.top)/ 2
r.left,r.top,top,bottom);
// 直角三角形
GradientTriangle(MemDC,r.right,r。 top,r.left +(r.right - r.left)/ 2 ,r.top +(r.bottom - r.top)/ 2
r.right,r.bottom,top,bottom);
}

void drawStrings(CDC * MemDC,RECT r)
{
// 标题的矩形
RECT rect,baner; // 正确定位所需
SIZE sBaner; // 正确定位所需
HFONT hf,hfOld;
long lfHeight;
rect.left = r.left;
rect.top = r.top;
rect.right = r.right;
rect.bottom = 120 ;
/ * ******************** ***中间橙色文字************************ /
/ / 通过函数的第一个参数设置下面的字体大小
lfHeight = -MulDiv( 14 ,GetDeviceCaps(MemDC,LOGPIXELSY), 72 );
hf = CreateFont(lfHeight, 0 0 0 ,FW_BOLD, 0 0 0 0 0 0 0 0 ,L Arial Black);
SetBkMode(MemDC,TRANSPARENT);
SetTextColor(MemDC,RGB( 255 163 94 )); // orange
hfOld =(HFONT)SelectObject(MemDC,hf); // 清理所需
GetTextExtentPoint32(MemDC,L ГЕОТЕРМАЛНИИНФОРМАЦИОНИСИСТЕМГРАДАБЕОГРАДА-ГЕОТЕРМИСТ
wcslen(L ГЕОТЕРМАЛНИИНФОРМАЦИОНИСИСТЕМГРАДАБЕОГРАДА-ГЕОТЕРМИСТ),& sBaner);
// 正确定位
baner.left = r.left + 60 ; baner.right = r.right - r.left - 60 ;
baner.top = r.top + 15 ; baner.bottom = r.top + sBaner.cy;
DrawTextEx( MemDC, L\"ГЕОТЕРМАЛНИ ИНФОРМАЦИОНИ СИСТЕМ ГРАДА БЕОГРАДА-ГЕОТЕРМИСТ\",
wcslen(L\"ГЕОТЕРМАЛНИ ИНФОРМАЦИОНИ СИСТЕМ ГРАДА БЕОГРАДА-ГЕОТЕРМИСТ\"), &baner,
DT_CENTER | DT_VCENTER | DT_NOCLIP | DT_WORDBREAK, 0 );
SelectObject( MemDC, hfOld ); // proper cleanup
DeleteObject( hf );
/******************************* top left text ************************/
//position it properly
baner.left = r.left + 90;
baner.top = r.top + sBaner.cy + 28;
baner.right = 460;
baner.bottom = r.bottom;
lfHeight = -MulDiv( 8, GetDeviceCaps( MemDC, LOGPIXELSY), 72 );
hf = CreateFont( lfHeight, 0, 0, 0, FW_BOLD, 0, 0, 0, 0, 0, 0, 0, 0, L\"Arial Black\" );
SetTextColor( MemDC, RGB( 0, 0, 0 ) );
hfOld = (HFONT)SelectObject( MemDC, hf ); // needed for proper cleanup
DrawTextEx( MemDC, L\"УПРАВА ГРАДА БЕОГРАДА\nСЕКРЕТАРИЈАТ ЗА КОМУНАЛНЕ И СТАМБЕНЕ ПОСЛОВЕ\nУПРАВА ЗА ЕНЕРГЕТИКУ\",
\t wcslen(L\"УПРАВА ГРАДА БЕОГРАДА\nСЕКРЕТАРИЈАТ ЗА КОМУНАЛНЕ И СТАМБЕНЕ ПОСЛОВЕ\nУПРАВА ЗА ЕНЕРГЕТИКУ\"),
\t\t\t&baner, DT_CENTER | DT_NOCLIP | DT_WORDBREAK, 0 );
/*************************** top right text *************************/
// position it properly
baner.top = r.top + sBaner.cy + 28;
baner.left = r.right - 350;
baner.right = r.right - 100;
baner.bottom = r.bottom;
DrawTextEx( MemDC, L\"УНИВЕРЗИТЕТ У БЕОГРАДУ\nРУДАРСКО ГЕОЛОШКИ ФАКУЛТЕТ\nДЕПАРТМАН ЗА ХИДРОГЕОЛОГИЈУ\",
\t\t\twcslen(L\"УНИВЕРЗИТЕТ У БЕОГРАДУ\nРУДАРСКО ГЕОЛОШКИ ФАКУЛТЕТ\nДЕПАРТМАН ЗА ХИДРОГЕОЛОГИЈУ\"),
\t\t\t&baner, DT_CENTER | DT_VCENTER | DT_NOCLIP | DT_WORDBREAK, 0 );
SelectObject( MemDC, hfOld ); // proper cleanup
DeleteObject( hf );
//========= draw right text in status bar =============//
lfHeight = -MulDiv( 8, GetDeviceCaps( MemDC, LOGPIXELSY), 72 );
hf = CreateFont( lfHeight, 0, 0, 0, FW_BOLD, TRUE, 0, 0, 0, 0, 0, 0, 0, L\"Arial Black\" );
hfOld = (HFONT)SelectObject( MemDC, hf ); // needed for proper cleanup
GetTextExtentPoint32( MemDC, L\"ЦЕНТАР ЗА ОБНОВЉИВЕ ВОДНЕ ЕНЕРГЕТСКЕ РЕСУРСЕ\",
\t\t\twcslen(L\"ЦЕНТАР ЗА ОБНОВЉИВЕ ВОДНЕ ЕНЕРГЕТСКЕ РЕСУРСЕ\"), &sBaner );
// position it properly
rect.bottom = r.bottom;
rect.right = r.left + sBaner.cx + 30;
rect.left = r.left + 30;
rect.top = r.bottom - r.top - 30;
// draw it to the back buffer
DrawTextEx( MemDC, L\"РУДАРСКО ГЕОЛОШКИ ФАКУЛТЕТ\nЦЕНТАР ЗА ОБНОВЉИВЕ ВОДНЕ ЕНЕРГЕТСКЕ РЕСУРСЕ\",
wcslen(L\"РУДАРСКО ГЕОЛОШКИ ФАКУЛТЕТ\nЦЕНТАР ЗА ОБНОВЉИВЕ ВОДНЕ ЕНЕРГЕТСКЕ РЕСУРСЕ\"),
&rect, DT_CENTER | DT_VCENTER | DT_NOCLIP | DT_WORDBREAK, 0 );
SelectObject( MemDC, hfOld ); // proper cleanup
DeleteObject( hf );
//============== right text in the status bar ==================//
lfHeight = -MulDiv( 10, GetDeviceCaps( MemDC, LOGPIXELSY), 72 );
hf = CreateFont( lfHeight, 0, 0, 0, FW_BOLD, TRUE, 0, 0, 0, 0, 0, 0, 0, L\"Arial\" );
hfOld = (HFONT)SelectObject( MemDC, hf ); // needed for proper cleanup
GetTextExtentPoint32( MemDC, L\" Дејан Миленић & Ана Врањеш © 2013 сва права задржана\",
wcslen(L\" Дејан Миленић & Ана Врањеш © 2013 сва права задржана\"), &sBaner );
// position it properly
rect.bottom = r.bottom;
rect.right = r.right - 10;
rect.left = r.right - r.left - sBaner.cx - 10;
rect.top = r.bottom - r.top - sBaner.cy;
// draw it to the back buffer
DrawTextEx( MemDC, L\" Дејан Миленић & Ана Врањеш © 2013 сва права задржана\",
\t\t\twcslen(L\" Дејан Миленић & Ана Врањеш © 2013 сва права задржана\"),
\t\t\t&rect, DT_CENTER | DT_VCENTER | DT_NOCLIP | DT_WORDBREAK | DT_NOPREFIX, 0 );
// perform proper cleanup
SelectObject( MemDC, hfOld );
DeleteObject(hf);
/****************** draw static control's background ******************/
//=============== top left blue static control ================//
//position it properly
rect.left = ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
rect.top = 230 + ( r.bottom - r.top - 450 ) / 3;
rect.right = 150 + ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
rect.bottom = 270 + ( r.bottom - r.top - 450 ) / 3;
// draw text
// set font size below via function's first argument
lfHeight = -MulDiv( 8, GetDeviceCaps( MemDC, LOGPIXELSY ), 72);
hf = CreateFont( lfHeight, 0, 0, 0, FW_BOLD, 0, 0, 0, 0, 0, 0, 0, 0, L\"Arial Black\");
hfOld = (HFONT)SelectObject( MemDC, hf );
DrawTextEx( MemDC, L\"УНОС ПОДАТАКА\", wcslen(L\"УНОС ПОДАТАКА\"),
&rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_WORDBREAK, 0 );
//================= top right blue static control =====================//
//position it properly
rect.left = 150 + 2 * ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
rect.top = 230 + ( r.bottom - r.top - 450 ) / 3;
rect.right = 300 + 2 * ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
rect.bottom = 270 + ( r.bottom - r.top - 450 ) / 3;
// draw text
DrawTextEx( MemDC, L\"ПРЕГЛЕД ПОДАТАКА\", wcslen(L\"ПРЕГЛЕД ПОДАТАКА\"),
\t &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_WORDBREAK, 0 );
//================= bottom left blue static control =====================//
//position it properly
rect.left = ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
rect.top = 380 + 2 * ( r.bottom - r.top - 450 ) / 3;
rect.right = 150 + ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
rect.bottom = 420 + 2 * ( r.bottom - r.top - 450 ) / 3;
// draw text
DrawTextEx( MemDC, L\"ИЗВЕШТАЈ\", wcslen(L\"ИЗВЕШТАЈ\"),
&rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_WORDBREAK, 0 );
//================= bottom right blue static control =====================//
//position it properly
rect.left = 150 + 2 * ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
rect.top = 380 + 2 * ( r.bottom - r.top - 450 ) / 3;
rect.right = 300 + 2 * ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
rect.bottom = 420 + 2 * ( r.bottom - r.top - 450 ) / 3;
// draw text
DrawTextEx( MemDC, L\"ПРЕТРАГА\", wcslen(L\"ПРЕТРАГА\"),
&rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_WORDBREAK, 0 );
SelectObject( MemDC, hfOld );
DeleteObject(hf);
//================ text for orange static controls =============//
// first one
rect.left = 3 * ( r.right - r.left ) / 4 + 10;
rect.top = r.top + 160;
rect.right = r.right - r.top - 50;
rect.bottom = r.top + 180;
//============= draw text ======//
lfHeight = -MulDiv( 10, GetDeviceCaps( MemDC, LOGPIXELSY ), 72);
hf = CreateFont(lfHeight, 0, 0, 0, FW_BOLD, 0, 0, 0, 0, 0, 0, 0, 0,L\"Arial Unicode MS\");
hfOld = (HFONT)SelectObject( MemDC, hf );
DrawTextEx( MemDC, L\"ИНФОРМАЦИЈЕ\", wcslen(L\"ИНФОРМАЦИЈЕ\"), &rect,
DT_VCENTER | DT_LEFT | DT_SINGLELINE, 0 );
// second one
rect.left = 3 * ( r.right - r.left ) / 4 + 10;
rect.top = r.top + 200;
rect.bottom = r.top + 220;
//====== draw text ======//
DrawTextEx( MemDC, L\"ПОМОЋ\", wcslen(L\"ПОМОЋ\"), &rect,
\t\t DT_VCENTER | DT_LEFT | DT_SINGLELINE, 0 );
// third one
rect.left = 3 * ( r.right - r.left ) / 4 + 10;
rect.top = r.top + 240;
rect.bottom = r.top + 260;
//====== draw text ======//
DrawTextEx( MemDC, L\"КОРИСНИ ЛИНКОВИ\", wcslen(L\"КОРИСНИ ЛИНКОВИ\"), &rect,
DT_VCENTER | DT_LEFT | DT_SINGLELINE, 0 );
// font is no longer needed, so do cleanup
SelectObject( MemDC, hfOld );
DeleteObject(hf);
}
/*
void drawImages( HDC hdc, CDC* MemDC, RECT r )
{
HDC hdcMemImg = CreateCompatibleDC(hdc); // back buffer for bitmaps
RECT rect = { 0, 0, 0, 0 }; // needed for proper positioning
//******************* top middle logo ******************
BITMAP b;
memset( &b, 0 , sizeof(BITMAP) );
GetObject( bmpSimbol, sizeof(BITMAP), &b );
// needed for proper cleanup
// ( we select a bitmap from resource file )
HBITMAP oldBmp = (HBITMAP)SelectObject( hdcMemImg, bmpSimbol );
// draw bitmap to the back buffer
TransparentBlt( MemDC, ( r.right - r.left - 64 ) / 2, r.top + 45, 64, 64,
hdcMemImg, 0, 0, b.bmWidth, b.bmHeight, RGB( 0, 0, 0) );

\t\tTransparentBlt(int xDest, int yDest, int nDestWidth,
\t\t\tint nDestHeight, CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth,
\t\t\tint nSrcHeight, UINT crTransparent)
SelectObject( hdcMemImg, oldBmp ); // proper cleanup

//=============== top left blue static control ================//
//position it properly
rect.left = ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
rect.top = 120 + ( r.bottom - r.top - 450 ) / 3;
rect.right = 150 + ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
rect.bottom = 270 + ( r.bottom - r.top - 450 ) / 3;
memset( &b, 0, sizeof(BITMAP) );
GetObject( bmpBTN1, sizeof(BITMAP), &b );
oldBmp = (HBITMAP)SelectObject( hdcMemImg, bmpBTN1 );
// draw bitmap on back buffer
TransparentBlt( MemDC, rect.left + 20, rect.top + 10, rect.right - rect.left - 30,
rect.bottom - rect.top - 40,
hdcMemImg, 0, 0, b.bmWidth, b.bmHeight, RGB( 0, 0, 0 ) );
SelectObject( hdcMemImg, oldBmp );
//================= top right blue static control =====================//
//position it properly
rect.left = 150 + 2 * ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
rect.top = 120 + ( r.bottom - r.top - 450 ) / 3;
rect.right = 300 + 2 * ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
rect.bottom = 270 + ( r.bottom - r.top - 450 ) / 3;
memset( &b, 0, sizeof(BITMAP) );
GetObject( bmpBTN2, sizeof(BITMAP), &b );
oldBmp = (HBITMAP)SelectObject( hdcMemImg, bmpBTN2 );
// draw bitmap on back buffer
TransparentBlt( MemDC, rect.left + 15, rect.top + 10, rect.right - rect.left - 30,
rect.bottom - rect.top - 40, hdcMemImg, 0, 0, b.bmWidth, b.bmHeight, RGB( 255, 0, 255 ) );
SelectObject( hdcMemImg, oldBmp );
//================= bottom left blue static control =====================//
//position it properly
rect.left = ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
rect.top = 270 + 2 * ( r.bottom - r.top - 450 ) / 3;
rect.right = 150 + ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
rect.bottom = 420 + 2 * ( r.bottom - r.top - 450 ) / 3;
memset( &b, 0, sizeof(BITMAP) );
GetObject( bmpBTN3, sizeof(BITMAP), &b );
oldBmp = (HBITMAP)SelectObject( hdcMemImg, bmpBTN3 );
// draw left bitmap on back buffer
TransparentBlt( MemDC, rect.left + 5, rect.top + 20, ( rect.right - rect.left) / 2,
\t rect.bottom - rect.top - 60, hdcMemImg, 0, 0, b.bmWidth, b.bmHeight, RGB( 0, 0, 0 ) );
SelectObject( hdcMemImg, oldBmp );
// draw right bitmap on back buffer
memset( &b, 0 , sizeof(BITMAP) );
GetObject( bmpBTN3a, sizeof(BITMAP), &b );
oldBmp = (HBITMAP)SelectObject( hdcMemImg, bmpBTN3a );
TransparentBlt( MemDC, rect.left + ( rect.right - rect.left) / 2 + 5, rect.top + 20,
( rect.right - rect.left) / 2 - 5, rect.bottom - rect.top - 60,
hdcMemImg, 0, 0, b.bmWidth, b.bmHeight, RGB( 0, 0, 0 ) );
SelectObject( hdcMemImg, oldBmp );
//position it properly
rect.left = 150 + 2 * ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
rect.top = 270 + 2 * ( r.bottom - r.top - 450 ) / 3;
rect.right = 300 + 2 * ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
rect.bottom = 420 + 2 * ( r.bottom - r.top - 450 ) / 3;
memset( &b, 0, sizeof(BITMAP) );
GetObject( bmpBTN4, sizeof(BITMAP), &b );
oldBmp = (HBITMAP)SelectObject( hdcMemImg, bmpBTN4 );
// draw bitmap on back buffer
TransparentBlt( MemDC, rect.left + 25, rect.top + 10, rect.right - rect.left - 50,
rect.bottom - rect.top - 40, hdcMemImg, 0, 0, b.bmWidth, b.bmHeight, RGB( 0, 0, 0 ) );
SelectObject( hdcMemImg, oldBmp );
//================= static controls on orange panel ==================//
// first one
rect.left = 3 * ( r.right - r.left ) / 4 - 30;
rect.top = r.top + 150;
rect.right = r.right - r.top - 50;
rect.bottom = r.top + 180;
memset( &b, 0, sizeof(BITMAP) );
GetObject( bmpInfo, sizeof(BITMAP), &b );
oldBmp = (HBITMAP)SelectObject( hdcMemImg, bmpInfo );
// draw bitmap on back buffer
TransparentBlt( MemDC, rect.left, rect.top, 30, 30, hdcMemImg, 0, 0,
b.bmWidth, b.bmHeight, RGB( 255, 163, 94 ) );
SelectObject( hdcMemImg, oldBmp );
// second one
rect.left = 3 * ( r.right - r.left ) / 4 - 30;
rect.top = r.top + 190;
rect.bottom = r.top + 220;
//=============== draw bitmap =============//
memset( &b, 0, sizeof(BITMAP) );
GetObject( bmpHelp, sizeof(BITMAP), &b );
oldBmp = (HBITMAP)SelectObject( hdcMemImg, bmpHelp );
// draw bitmap on back buffer
TransparentBlt( MemDC, rect.left, rect.top, 30, 30, hdcMemImg, 0, 0,
b.bmWidth, b.bmHeight, RGB( 255, 163, 94 ) );
SelectObject( hdcMemImg, oldBmp );
// third one
rect.left = 3 * ( r.right - r.left ) / 4 - 30;
rect.top = r.top + 230;
rect.bottom = r.top + 260;
//=============== draw bitmap =============//
memset( &b, 0, sizeof(BITMAP) );
GetObject( bmpLink, sizeof(BITMAP), &b );
oldBmp = (HBITMAP)SelectObject( hdcMemImg, bmpLink );
// draw bitmap on back buffer
TransparentBlt( MemDC, rect.left, rect.top, 30, 30, hdcMemImg, 0, 0,
b.bmWidth, b.bmHeight, RGB( 255, 163, 94 ) );
SelectObject( hdcMemImg, oldBmp );
//========= draw EMF and PNG files =========//
Graphics graphics( MemDC );
\t\t/******* fourth orange static control with the map ( EMF file ) ********
// proper positioning
rect.top = r.top + 270;
rect.bottom = r.bottom - 60;
\t rect.left = 3 * ( r.right - r.left ) / 4 - 30;
//============= aspect ratio ================//
UINT o_height = btn5->GetHeight(), o_width = btn5->GetWidth();
float scale = 0.5; int mapPosX, mapPosY;
\t scale = (float)( rect.right - rect.left ) / o_width;
if( (float)( rect.bottom - rect.top ) / o_height < scale )
\t {
scale = (float)( rect.bottom - rect.top ) / o_height;
int marginX = ( rect.right - rect.left ) - (int)( o_width * scale );
\t\t\tint marginY = ( rect.bottom - rect.top ) - (int)( o_height * scale );
\t\t\tmarginX /= 2; marginY /= 2; mapPosX = rect.left + marginX;
\t\t\tmapPosY = rect.top + marginY;
\t\t\tgraphics.DrawImage( btn5, mapPosX, mapPosY, (int)( o_width * scale ),
\t\t\t\t\t(int)( o_height * scale ) );
/******************** top left logo ( PNG file ) *******************
o_height = image->GetHeight();
\t\t\to_width = image->GetWidth();
graphics.DrawImage( image, r.left + 5, r.top + 10, o_width, o_height );
/******************** top right logo ( PNG file ) ******************
\t\t\to_height = image1->GetHeight();
o_width = image1->GetWidth();
\t\t\tgraphics.DrawImage( image1, r.right - r.left - 90, r.top + 10, o_width, o_height );
}
\t\tDeleteDC(hdcMemImg); // release memory DC
}
*/

void OnDraw( CDC* pDC)
{
\tRECT r; HWND hwnd;
GetClientRect(hwnd, &r);
CreateCompatibleDC(pDC->m_hDC); // back buffer
\tCBitmap bmp = CreateCompatibleBitmap(pDC->m_hDC, r.right - r.left, r.bottom - r.top),
\tCBitmap oldBmp = SelectObject(&bmp); // needed for cleanup
/*************** draw banner ******************/
// position it properly at the top
RECT rect;
rect.left = r.left;
rect.top = r.top;
rect.right = r.right;
rect.bottom = 120;
// draw background for middle part of the window
drawBackground( pDC, r );
//draw header with grid lines
drawHeader( pDC, rect, hbPozadina );
// draw \"status bar\"
drawFooter( pDC, r, RGB( 0x48, 0xAC, 0xC6), RGB( 0x31, 0x83, 0x99 ) );
/****************** draw static control's background ******************/
//=============== top left static control ================//
//position it properly
rect.left = ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
rect.top = 120 + ( r.bottom - r.top - 450 ) / 3;
rect.right = 150 + ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
rect.bottom = 270 + ( r.bottom - r.top - 450 ) / 3;
// draw gradient button
FillButton( pDC, rect, BlueFrame );
//================= top right static control =====================//
//position it properly
rect.left = 150 + 2 * ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
rect.top = 120 + ( r.bottom - r.top - 450 ) / 3;
rect.right = 300 + 2 * ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
rect.bottom = 270 + ( r.bottom - r.top - 450 ) / 3;
// draw gradient button
FillButton( pDC, rect, BlueFrame );
//================= bottom left static control =====================//
//position it properly
rect.left = ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
rect.top = 270 + 2 * ( r.bottom - r.top - 450 ) / 3;
rect.right = 150 + ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
rect.bottom = 420 + 2 * ( r.bottom - r.top - 450 ) / 3;
// draw gradient button
FillButton( pDC, rect, BlueFrame );
//================= bottom right static control =====================//
//position it properly
rect.left = 150 + 2 * ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
\t\trect.top = 270 + 2 * ( r.bottom - r.top - 450 ) / 3;
\t\trect.right = 300 + 2 * ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
\t\trect.bottom = 420 + 2 * ( r.bottom - r.top - 450 ) / 3;
// draw gradient button
FillButton( pDC, rect, BlueFrame );
//======================== draw orange panel =================//
//position it properly
rect.left = 3 * ( r.right - r.left ) / 4 - 40;
rect.top = r.top + 140;
rect.right = rect.left + ( r.right - r.left ) / 4;
rect.bottom = rect.top + ( r.bottom - r.top - 190 );
drawOrangePanel( pDC, rect, RGB( 0xFF, 0xC8, 0xAA ), RGB( 0xFF, 0x96, 0x48 ) );
// draw all the text
drawStrings( pDC, r );
// draw all the bitmaps and EMF files
drawImages( hdc, MemDC, r );
/****************** draw back buffer on the screen DC *****************/
BitBlt(0, 0, r.right - r.left, r.bottom - r.top, pDC, 0, 0, SRCCOPY );
/************** cleanup *******************/
SelectObject(oldBmp );
DeleteObject(bmp); // compatible bitmap for MemDC
}

// WinMain's procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
\t\t\t{
\t\t\t\timage = Image::FromFile(L\".\\resources\\BG.png\"), // upper left logo
image1 = Image::FromFile(L\".\\resources\\RGF.png\"); // upper right logo
\t\t\t\tbtn5 = Image::FromFile(L\".\\resources\\BTN5.emf\"); // map in the bottom of the orange button
// load gray background brush for the top banner
hbPozadina = CreateSolidBrush( RGB( 230, 230, 230 ) );
// load left icon in the status bar
hiAdmin = LoadIcon( hInst, MAKEINTRESOURCE(IDI_ICON2) );
// bitmaps for static controls
bmpBTN1 = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP1) );
bmpBTN2 = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP10) );
/** these two bitmaps make one image for the bottom right blue static control **/
bmpBTN3 = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP3) );
bmpBTN3a = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP5) );
//**********************************************************************//
bmpBTN4 = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP4) );
bmpSimbol = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP16) );
bmpInfo = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP6) );
\t\t\t\tbmpLink = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP7) );
\t\t\t\tbmpHelp = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP8) );
//******** brushes ***********//
// brush for orange panel that holds 3 static controls and a map
\t\t\t\thbr = CreateSolidBrush( RGB( 255, 163, 94 ) );
// blue frame for blue static controls
BlueFrame = CreateSolidBrush( RGB(79, 129, 189) );
/*******************************************/
// get rectangle dimensions of the main window
\t\t\t\tRECT rec;
\t\t\t\tGetClientRect( hwnd, &rec );
/******* main window's static controls ******/
// top left
\t\t\t\tHWND hsUnosPodataka = CreateWindowEx( 0, L\"Static\", L\"\", WS_VISIBLE | WS_CHILD | SS_NOTIFY,
\t\t\t\t\t\t\t( 3 * ( rec.right - rec.left ) / 4 - 340 ) / 3,
\t\t\t\t\t\t 120 + ( rec.bottom - rec.top - 450 ) / 3,
\t\t\t\t\t\t 150, 150, hwnd, (HMENU)4000, hInst, 0);
// top right
\t\t\t\tHWND hsPregledPodataka = CreateWindowEx( 0, L\"Static\", L\"\", WS_VISIBLE | WS_CHILD | SS_NOTIFY,
150 + 2 * ( 3 * ( rec.right - rec.left ) / 4 - 340 ) / 3,
\t\t\t\t\t\t 120 + ( rec.bottom - rec.top - 450 ) / 3,
\t\t\t\t\t\t 150, 150, hwnd, (HMENU)4001, hInst, 0);
// bottom left
\t\t\t\tHWND hsIzvestaj = CreateWindowEx(0, L\"Static\", L\"\", WS_VISIBLE | WS_CHILD | SS_NOTIFY,
\t ( 3 * ( rec.right - rec.left ) / 4 - 340 ) / 3,
\t\t\t\t\t\t 270 + 2 * ( rec.bottom - rec.top - 450 ) / 3,
\t\t\t\t\t\t 150, 150, hwnd, (HMENU)4002, hInst, 0);
// bottom right
\t\t\t\tHWND hsPretraga = CreateWindowEx(0, L\"Static\", L\"\", WS_VISIBLE | WS_CHILD | SS_NOTIFY,
150 + 2 * ( 3 * ( rec.right - rec.left ) / 4 - 340 ) / 3,
270 + 2 * ( rec.bottom - rec.top - 450 ) / 3,
150, 150, hwnd, (HMENU)4003, h Inst, 0);
//============= static controls on the orange panel ==============//
// first one from the top
\t\t\t\tHWND hsInfoInfo = CreateWindowEx(0, L\"Static\", L\"\", WS_VISIBLE | WS_CHILD | SS_NOTIFY,
3 * ( rec.right - rec.left ) / 4 - 30, rec.top + 150,
\t\t\t\t\t\t\t( rec.right - rec.left ) / 4 - 20, 30, hwnd, (HMENU)4007, hInst, 0);
// second one from the top
\t\t\t\tHWND hsInfoHelp = CreateWindowEx(0, L\"Static\", L\"\", WS_VISIBLE | WS_CHILD | SS_NOTIFY,
3 * ( rec.right - rec.left ) / 4 - 30, rec.top + 190,
\t\t\t\t\t\t ( rec.right - rec.left ) / 4 - 20, 30, hwnd, (HMENU)4009, hInst, 0);
// third one from the top
\t\t\t\tHWND hsInfoLink = CreateWindowEx(0, L\"Static\", L\"\", WS_VISIBLE | WS_CHILD | SS_NOTIFY,
3 * ( rec.right - rec.left ) / 4 - 30, rec.top + 230,
\t\t\t\t\t\t ( rec.right - rec.left ) / 4 - 20, 30, hwnd, (HMENU)4008, hInst, 0);
// fourth one-it will contain a map
\t\t\t\tHWND hsInfoKarta = CreateWindowEx(0, L\"Static\", L\"\", WS_VISIBLE | WS_CHILD | SS_NOTIFY,
\t 3 * ( rec.right - rec.left ) / 4 - 30, rec.top + 270,
\t\t\t\t\t\t ( rec.right - rec.left ) / 4 - 20, rec.bottom - rec.top - 330,
\t\t\t\t\t\t hwnd, (HMENU)4010, hInst, 0);
\t\t\t}
\t\t\treturn (LRESULT)0;
\t\tcase WM_COMMAND:
\t\t\t{
\t\t\t\tswitch (LOWORD(wParam))
\t\t\t\t{
\t\t\t\tcase 4000:
\t\t\t\tcase 4001:
\t\t\t\tcase 4002:
\t\t\t\tcase 4003:
\t\t\t\tcase 4007:
\t\t\t\tcase 4008:
\t\t\t\tcase 4009:
\t\t\t\tcase 4010:
\t\t\t\t\tMessageBeep(MB_ICONEXCLAMATION);
\t\t\t\t\tbreak;
\t\t\t\tdefault:
\t\t\t\t\treturn DefWindowProc(hwnd, msg, wParam, lParam);
\t\t\t\t}
\t\t\t\tbreak;
\t\t\t}
case WM_ERASEBKGND:
\t\t\treturn (LRESULT)1; // so we avoid flicker ( all painting is in WM_PAINT )
case WM_PAINT:
\t\t\t{
// paint the picture
\t\t\t\tCDC* pDC = GetWindowDC(hwnd);
\t\t\t\tOnDraw(pDC);
}
\t\t\treturn (LRESULT)0;
case WM_SIZE:
{
\t RECT rec;
GetClientRect( hwnd, &rec );
SetWindowPos( GetDlgItem( hwnd, 4000 ), NULL, ( 3 * ( rec.right - rec.left ) / 4 - 340 ) / 3,
120 + ( rec.bottom - rec.top - 450 ) / 3, 150, 150,
SWP_NOZORDER | SWP_NOCOPYBITS );
SetWindowPos( GetDlgItem( hwnd, 4001 ), NULL, 150 + 2 * ( 3 * ( rec.right - rec.left ) / 4 - 340 ) / 3,
\t\t\t\t\t\t\t120 + ( rec.bottom - rec.top - 450 ) / 3, 150, 150, SWP_NOZORDER | SWP_NOCOPYBITS);
SetWindowPos( GetDlgItem( hwnd, 4002 ), NULL, ( 3 * ( rec.right - rec.left ) / 4 - 340 ) / 3,
\t\t\t\t 270 + 2 * ( rec.bottom - rec.top - 450 ) / 3, 150, 150, SWP_NOZORDER | SWP_NOCOPYBITS );
SetWindowPos( GetDlgItem( hwnd, 4003 ), NULL, 150 + 2 * ( 3 * ( rec.right - rec.left ) / 4 - 340 ) / 3,
\t\t\t\t 270 + 2 * ( rec.bottom - rec.top - 450 ) / 3, 150, 150, SWP_NOZORDER | SWP_NOCOPYBITS );
SetWindowPos( GetDlgItem( hwnd, 4007 ), NULL, 3 * ( rec.right - rec.left ) / 4 - 30, rec.top + 150,
\t\t\t\t\t\t\t( rec.right - rec.left ) / 4 - 20, 30, SWP_NOZORDER | SWP_NOCOPYBITS );
SetWindowPos( GetDlgItem( hwnd, 4008 ), NULL, 3 * ( rec.right - rec.left ) / 4 - 30, rec.top + 190,
\t\t\t\t\t\t\t( rec.right - rec.left ) / 4 - 20, 30, SWP_NOZORDER | SWP_NOCOPYBITS );
SetWindowPos( GetDlgItem( hwnd, 4009 ), NULL, 3 * ( rec.right - rec.left ) / 4 - 30, rec.top + 230,
\t\t\t\t\t\t\t( rec.right - rec.left ) / 4 - 20, 30, SWP_NOZORDER | SWP_NOCOPYBITS );
SetWindowPos( GetDlgItem( hwnd, 4010 ), NULL, 3 * ( rec.right - rec.left ) / 4 - 30, rec.top + 270,
\t\t\t\t\t\t\t( rec.right - rec.left ) / 4 - 20, rec.bottom - rec.top - 330, SWP_NOZORDER | SWP_NOCOPYBITS );
\t\t\t\tInvalidateRect( hwnd, NULL, FALSE );
}
\t\t\treturn (LRESULT)0;
\t\tcase WM_CTLCOLORSTATIC:
return (LRESULT)( (HBRUSH)GetStockObject(NULL_BRUSH) );
\t\tcase WM_CLOSE:
\t\t\t{
DeleteObject(bmpSimbol);
DeleteObject(bmpBTN1);
DeleteObject(bmpBTN2);
DeleteObject(bmpBTN3);
DeleteObject(bmpBTN4);
DeleteObject(bmpInfo);
DeleteObject(bmpLink);
DeleteObject(bmpHelp);
DestroyIcon(hIcon);
DestroyIcon(hiAdmin);
DeleteObject(hbPozadina);
DeleteObject(hbr);
DeleteObject(BlueFrame);
delete image;
delete image1;
delete btn5;
DestroyWindow(hwnd);
\t\t\t}
\t\t\treturn (LRESULT)0;
\t\tcase WM_DESTROY:
\t\t\t{
PostQuitMessage(0);
\t\t\t}
return (LRESULT)0;
default:
\t\treturn DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
// WinMain
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// store hInstance in global variable for later use
\thInst = hInstance; // load main icon
hIcon = LoadIcon( hInst, MAKEINTRESOURCE(IDI_ICON1));
WNDCLASSEX wc; HWND hwnd; MSG Msg;
/*********** variables for GDI+ initialization *****************/
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
/************** Initialize GDI+. *************************/
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
/*************** finished GDI+ initialisation ********************/
// initialize common controls
INITCOMMONCONTROLSEX iccex;
\ticcex.dwSize = sizeof(INITCOMMONCONTROLSEX);
\ticcex.dwICC = ICC_STANDARD_CLASSES ;
\tInitCommonControlsEx(&iccex);
// register main window class
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = hIcon;
\twc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
wc.lpszMenuName = NULL;
wc.lpszClassName = L\"Main_Window\";
wc.hIconSm = hIcon;
if(!RegisterClassEx(&wc))
{
\t MessageBox(NULL, L\"Window Registration Failed!\", L\"Error!\", MB_ICONEXCLAMATION | MB_OK);
return 0;
\t}
// create main window
hwnd = CreateWindowEx( 0, L\"Main_Window\", L\"Геотермист\", WS_OVERLAPPEDWINDOW,
\t\t( GetSystemMetrics(SM_CXMAXIMIZED) - 1020 ) / 2,
\t\t( GetSystemMetrics(SM_CYMAXIMIZED) - 600 ) / 2,
\t\t1020, 600, NULL, NULL, hInstance, 0 );
if(hwnd == NULL)
\t{
\t\tMessageBox(NULL, L\"Window creation failed!\", L\"Error!\", MB_ICONEXCLAMATION | MB_OK);
return 0 ;
\t}
\tShowWindow(hwnd, nCmdShow);
\tUpdateWindow(hwnd);
\twhile(GetMessage(&Msg, NULL, 0, 0) > 0)
\t{
\t TranslateMessage(&Msg);
\t\tDispatchMessage(&Msg);
\t}
// shutdownd GDI+
GdiplusShutdown(gdiplusToken);
\treturn Msg.wParam;
}


</gdiplus.h></commctrl.h></windowsx.h></afxwin.h></windows.h>


INTRODUCTION AND RELEVANT INFORMATION:

I have a complex painting to implement in my main window’s WM_PAINT handler.

I have submitted a picture bellow to illustrate it:
http://pbrd.co/18fNYYp[^]

Main window has static controls, instead of buttons, which have style SS_NOTIFY.
When user clicks on them, certain actions occur in program, which are irrelevant for now.

The following picture shows where static controls in the main window are:
http://pbrd.co/18fOkya[^]

Map on the orange panel is an EMF file ,top left and right logos are PNG files, and other pictures are bitmaps.

Visual Styles are enabled via #pragma directive. I also use GDI+ along with the GDI.

Project was created as empty project and I have coded everything from "scratch".

In order to implement this task, I have decided to draw the entire picture in WM_PAINT, and to put transparent static controls over the images on the picture that correspond them.

In order to keep my code clean and simple, I have made functions that implement the above, so my WM_PAINT handler can be as small as possible.

Gradient brushes were made with the usage of GradientFill(...) API.

I work on Windows XP, using MS Visual Studio C++ 2008 Express Edition and pure Win32 API.

One note: since Express edition of VS doesn't have resource editor, resource file and resource header were created using ResEdit from here:
http://www.resedit.net/.[^]

UPDATE #1( updated on December 17th, 2013 ):

In order to make things easier for those trying to help, here is the single source file with minimal code that illustrates the problem: http://pastebin.com/BeAVHViC[^]

PROBLEM:

In order to avoid flickering, I have used double buffering, which I have learned from Paul Watt’s articles, Charles Petzold’s Programming Windows 5th edition and Forger’s WIN32 tutorial.

Theoretically speaking, everything is OK, and my code compiles without any errors.

I have pasted the code here:
http://pastebin.com/zSYT1i8L[^]

My English is not good enough to accurately describe the problems that I face ( all I can say is that edges of the main window and static control's redraw "slow" and they flicker ) so I have created a demo application that demonstrates them:
http://www.filedropper.com/geotermistgrafika[^]

MY EFFORTS TO SOLVE THE PROBLEM:

I have handled WM_ERASEBKGND ( returned (LRESULT)1 ), and I have excluded styles CS_VREDRAW and CS_HREDRAW from my window class-therefore flickering should not be caused because of this.

My window doesn’t have WS_CLIPCHILDREN style because part of the desktop picture is seen where static controls are.

In my WM_SIZE handler I have :
1. Repositioned static controls using SetWindowPos(...) API and reduced flickering by adding the SWP_NOCOPYBITS flag.

2. Invalidated the entire window with the InvalidateRect( hWnd, NULL, FALSE ), so this API does not send WM_ERASEBKGND when invalidating ( 3rd parameter is FALSE ), but even if I try with TRUE the effect is the same.

I have implemented double buffering for WM_PAINT handler like in the examples found in the above books/articles/tutorials ( by doing everything in the memory DC and do BitBlt(...) on screen DC in order to avoid flickering ).

I didn’t handle WM_SIZING, nor WM_WINDOWPOSCHANGING, or WM_MOVING message.

I have used the tool GDIView ( http://www.nirsoft.net/utils/gdi_handles.html[^] ) to track down GDI leaks.
Each time I resize/maximize my window, GDIView shows +4 in column for regions, which should mean that I leak regions but I can’t figure out how is this possible, since I do not use API’s that manipulate with regions, and have double checked everything.

In my opinion everything should be fine and maybe this is irrelevant, but I just thought to mention it, in case it is important.

If I add WS_EX_COMPOSITED style to the main window, the performance does not improve.

I have tried to find online example that would help me to solve my problem but all the tutorials are simple and do not cover this type of complex pictures.

IMPORTANT NOTE:

Before improving this question, I got two solutions suggested, one of them advising me to do as much as I can in WM_ERASEBKGND.

After leaving my WM_PAINT handler empty and calling onPaint function in WM_ERASEBKGND with the device context obtained with GetDC(..) API, the flickering disappeared, but during the resizing, redrawing of the window was "spiky" and the problem with the edges of the main window was not solved.
Still, this is much better improvement than the original code.

UPDATE ( December, 17th 2013 ):

After removing the call drawImages( hdc, MemDC, r ); from onPaint, the flickering of the edges occurs again.

It seems less, and the number of regions GDIView detects as leaked is reduced by one.

QUESTION:

How to get rid of the problems demonstrated in my demo application, provided above?

I hereby thank anyone who invests its time and efforts to try to help me.

Best regards.

解决方案

CPallini is absolutly right. Painting with WM_PAINT or the OnPaint method leads to flickering. Draw most things with the WM_ERASEBKGND message.

read some articles about "paint for beginners". Key is to avoid redrawing.

http://www.codeproject.com/search.aspx?q=paint+for+beginners&x=-1262&y=-146&sbo=kw[^]

I solve these problem via iterating: only draw one piece and if it works, i activate the next as long as it work...

Tip: dont work with controls, but check the mouse coordinates and handle it via posting messages to the windows.


Here is what I did with it. I left the drawImages function for you to rewrite.
You should be able to use CBitmap and CBitmap* without breaking your code.

#include "resource.h"
#include <windows.h>
#include <afxwin.h>
#include <windowsx.h> // for TransparentBlt()
#include <commctrl.h>
#include <gdiplus.h>
#pragma comment( linker, "/manifestdependency:\"type='win32' \
                         name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
                         processorArchitecture='*' publicKeyToken='6595b64144ccf1df' \
                         language='*'\"")
#pragma comment( lib, "comctl32.lib")
#pragma comment( lib, "Msimg32.lib" ) // for TransparentBlt()
#pragma comment( lib, "Gdiplus.lib" )
using namespace Gdiplus;
// variable for storing the instance
static HINSTANCE hInst; 
// icons
static HICON hIcon, // main window's icon
hiAdmin; // icon in the left corner of the status bar
// Images for logos
Image *image, // left logo on main window's top banner
     *image1, // right logo on main window's top banner
     *btn5; // map for the orange static control
// variables for painting the window

static HBRUSH hbPozadina, // gray background brush for grid on the top
              BlueFrame, // needed to frame blue static controls
			  hbr; // orange brush for orange panel

static HBITMAP bmpBTN1, // image for top left blue static control
               bmpBTN2, // image for top right blue static control
			   //============ these two make one image =========== //
			   bmpBTN3, // left image for bottom left blue static control
			   bmpBTN3a, // right image for bottom left blue static control
			   //==================================================//
			   bmpBTN4, // image for bottom right blue static control
			   bmpSimbol, // middle logo on the main window's top banner
			   bmpInfo, // top left image for child window of the 1st orange static control
			   bmpLink, // top left image for child window of the 3rd orange static control
			   bmpHelp; // top left image for child window of the 2nd orange static control
/****************************** helper functions for WM_PAINT **************************/
// Fills triangle with gradient brush
void GradientTriangle( CDC* MemDC, LONG x1, LONG y1, LONG x2, LONG y2, LONG x3, LONG y3, 
                      COLORREF top, COLORREF bottom )
{
        TRIVERTEX vertex[3];
        vertex[0].x     = x1;
        vertex[0].y     = y1;
        vertex[0].Red   = GetRValue(bottom) << 8;
		vertex[0].Green = GetGValue(bottom) << 8;
		vertex[0].Blue  = GetBValue(bottom) << 8;
		vertex[0].Alpha = 0x0000;
		vertex[1].x     = x2;
		vertex[1].y     = y2;
		vertex[1].Red   = GetRValue(top) << 8;
		vertex[1].Green = GetGValue(top) << 8;
		vertex[1].Blue  = GetBValue(top) << 8;
		vertex[1].Alpha = 0x0000;
		vertex[2].x     = x3;
		vertex[2].y     = y3; 
		vertex[2].Red   = GetRValue(bottom) << 8;
		vertex[2].Green = GetGValue(bottom) << 8;
		vertex[2].Blue  = GetBValue(bottom) << 8;
		vertex[2].Alpha = 0x0000;
// Create a GRADIENT_TRIANGLE structure that
// references the TRIVERTEX vertices.
        GRADIENT_TRIANGLE gTriangle;
		gTriangle.Vertex1 = 0;
		gTriangle.Vertex2 = 1;
		gTriangle.Vertex3 = 2;
// Draw a shaded triangle.
        GradientFill( MemDC, vertex, 3, &gTriangle, 1, GRADIENT_FILL_TRIANGLE);
}
// draws the background for the part of the window between header and footer
void drawBackground( HDC MemDC, RECT r )
{
        /******************** main window's gradient background ***************/
	GradientTriangle( MemDC, r.right, r.bottom - r.top - 30, r.left, r.bottom - r.top - 30,
	          r.left, r.top + 120, RGB( 0x95, 0xB3, 0xD7 ), RGB( 0xDB, 0xE5, 0xF1 ) );
	GradientTriangle( MemDC, r.right, r.bottom - r.top - 30, r.right, r.top + 120,
	          r.left, r.top + 120, RGB( 0x95, 0xB3, 0xD7 ), RGB( 0xDB, 0xE5, 0xF1 ) );
}

// draws the header of the main window
void drawHeader( CDC* MemDC, RECT rect, HBRUSH hbPozadina )
{
     FillRect( MemDC, &rect, hbPozadina);  // draw grid on the banner background
     LOGBRUSH lbPozadina;
     HGDIOBJ hPenPozadina = NULL, hOldPenPozadina;
     lbPozadina.lbColor = RGB( 216, 216, 216 );
     lbPozadina.lbHatch = 0;
     lbPozadina.lbStyle = BS_SOLID;
     hPenPozadina = ExtCreatePen( PS_COSMETIC | PS_SOLID, 1, &lbPozadina, 0, NULL); 
     hOldPenPozadina = SelectObject( MemDC, hPenPozadina); // needed for cleanup
     for( int i = rect.left + 12; i< rect.right; i += 12)
     {
		MoveToEx( MemDC, i, rect.top, NULL );
		LineTo( MemDC, i, rect.bottom - rect.top + 1 );
	 }

     for( int i = rect.top + 12; i< rect.bottom; i += 12)
     {
         MoveToEx( MemDC, rect.left, i, NULL );
         LineTo( MemDC, rect.right - rect.left + 1, i );
     }
        // perform proper cleanup
     SelectObject( MemDC, hOldPenPozadina);
     DeleteObject(hPenPozadina);
/********* draw a line at the bottom of the top banner ******/
     LOGBRUSH lb;
     HGDIOBJ hPen = NULL, hOldPen;
     lb.lbColor = RGB( 0, 0, 0 );
     lb.lbHatch = 0;
     lb.lbStyle = BS_SOLID;
     hPen = ExtCreatePen( PS_COSMETIC | PS_SOLID, 1, &lb, 0, NULL); 
     hOldPen = SelectObject( MemDC, hPen ); // needed for proper cleanup
     MoveToEx( MemDC, rect.left, rect.top + 120, NULL );
     LineTo( MemDC, rect.right - rect.left + 1, rect.top + 120 );
     // perform proper cleanup
     SelectObject( MemDC, hOldPen );
     DeleteObject(hPen);
}
// fills rectangle with gradient brush
void GradientRectangle( CDC* MemDC, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF top, COLORREF bottom )
{
// vertexes for static's gradient color
        TRIVERTEX vertexS[2];
        vertexS[0].x     = x1;
        vertexS[0].y     = y1;
        vertexS[0].Red   = GetRValue(top) << 8;
        vertexS[0].Green = GetGValue(top) << 8;
        vertexS[0].Blue  = GetBValue(top) << 8;
        vertexS[0].Alpha = 0x0000;
        vertexS[1].x     = x2;
        vertexS[1].y     = y2; 
        vertexS[1].Red   = GetRValue(bottom) << 8;
        vertexS[1].Green = GetGValue(bottom) << 8;
        vertexS[1].Blue  = GetBValue(bottom) << 8;
        vertexS[1].Alpha = 0x0000;
        // Create a GRADIENT_RECT structure that 
        // references the TRIVERTEX vertices.
        GRADIENT_RECT gRect;
        gRect.UpperLeft  = 0;
        gRect.LowerRight = 1;
        // Draw a shaded rectangle. 
        GradientFill( MemDC, vertexS, 2, &gRect, 1, GRADIENT_FILL_RECT_V );
}
// fills the "button" with blue gradient and frames it with blue brush
void FillButton( CDC* MemDC, RECT rect, HBRUSH BlueFrame )
{
        // fill upper half of the rectangle
        GradientRectangle( MemDC, rect.left, rect.top, rect.right, rect.top + ( rect.bottom - rect.top ) / 2,
		RGB( 0x95, 0xB3, 0xD7 ), RGB( 0x4F, 0x8B, 0xBD ) );
        // fill bottom half of the rectangle
        GradientRectangle( MemDC, rect.left, rect.top + ( rect.bottom - rect.top ) / 2, 
		rect.right, rect.bottom, RGB( 0x4F, 0x8B, 0xBD ), RGB( 0x95, 0xB3, 0xD7 ) );
		FrameRect( MemDC, &rect, BlueFrame );
}
// draws the "status bar" at the bottom of the main window
void drawFooter( CDC* MemDC, RECT r, COLORREF top, COLORREF bottom )
{
// down triangle
	GradientTriangle( MemDC, r.right, r.bottom, ( r.right - r.left ) / 2, r.bottom - r.top - 15,
	                r.left, r.bottom, top, bottom );
// upper triangle
	GradientTriangle( MemDC, r.right, r.bottom - r.top - 30, ( r.right - r.left ) / 2, r.bottom - r.top - 15,
	                r.left, r.bottom - r.top - 30, top, bottom );
// left triangle
	GradientTriangle( MemDC, r.left, r.bottom, ( r.right - r.left ) / 2, r.bottom - r.top - 15,
	                r.left, r.bottom - r.top - 30, top, bottom );
// right triangle
    GradientTriangle( MemDC, r.right, r.bottom - r.top - 30, ( r.right - r.left ) / 2, r.bottom - r.top - 15, 
	                r.right, r.bottom, top, bottom );
// draw icon
	DrawIconEx( MemDC, r.left, r.bottom - r.top - 30, hiAdmin, 30, 30, NULL, NULL, DI_NORMAL );
}
// draw orange panel on which map and 3 static controls will be drawn
void drawOrangePanel( CDC* MemDC, RECT r, COLORREF top, COLORREF bottom )
{
 // down triangle
	GradientTriangle( MemDC, r.right, r.bottom, r.left + ( r.right - r.left ) / 2, r.top + ( r.bottom - r.top ) / 2,
	                r.left, r.bottom, top, bottom );
 // upper triangle
    GradientTriangle( MemDC, r.right, r.top, r.left + ( r.right - r.left ) / 2, r.top + ( r.bottom - r.top ) / 2,
					r.left, r.top, top, bottom );
// left triangle
    GradientTriangle( MemDC, r.left, r.bottom, r.left + ( r.right - r.left ) / 2, r.top + ( r.bottom - r.top ) / 2,
	                r.left, r.top, top, bottom );
// right triangle
    GradientTriangle( MemDC, r.right, r.top, r.left + ( r.right - r.left ) / 2, r.top + ( r.bottom - r.top ) / 2, 
	                r.right, r.bottom, top, bottom );
}

void drawStrings( CDC* MemDC, RECT r )
{
// rectangle for header
	RECT rect, baner; // needed for proper positioning
    SIZE sBaner; // needed for proper positioning
    HFONT hf, hfOld;
    long lfHeight;
    rect.left = r.left;
    rect.top = r.top;
    rect.right = r.right;
    rect.bottom = 120;
/************************ middle orange text ************************/
// set font size below via function's first argument 
    lfHeight = -MulDiv( 14, GetDeviceCaps( MemDC, LOGPIXELSY), 72 );
    hf = CreateFont( lfHeight, 0, 0, 0, FW_BOLD, 0, 0, 0, 0, 0, 0, 0, 0, L"Arial Black" );
    SetBkMode( MemDC, TRANSPARENT );
    SetTextColor( MemDC, RGB( 255, 163, 94 ) ); // orange
    hfOld = (HFONT)SelectObject( MemDC, hf ); // needed for cleanup
    GetTextExtentPoint32( MemDC, L"ГЕОТЕРМАЛНИ ИНФОРМАЦИОНИ СИСТЕМ ГРАДА БЕОГРАДА-ГЕОТЕРМИСТ",
	    wcslen(L"ГЕОТЕРМАЛНИ ИНФОРМАЦИОНИ СИСТЕМ ГРАДА БЕОГРАДА-ГЕОТЕРМИСТ"), &sBaner );
// proper positioning
        baner.left = r.left + 60;  baner.right = r.right - r.left - 60;
        baner.top = r.top + 15;    baner.bottom = r.top + sBaner.cy;
        DrawTextEx( MemDC, L"ГЕОТЕРМАЛНИ ИНФОРМАЦИОНИ СИСТЕМ ГРАДА БЕОГРАДА-ГЕОТЕРМИСТ",
           wcslen(L"ГЕОТЕРМАЛНИ ИНФОРМАЦИОНИ СИСТЕМ ГРАДА БЕОГРАДА-ГЕОТЕРМИСТ"), &baner,
           DT_CENTER | DT_VCENTER | DT_NOCLIP | DT_WORDBREAK, 0 );
        SelectObject( MemDC, hfOld ); // proper cleanup
        DeleteObject( hf );
/******************************* top left text ************************/
//position it properly
        baner.left = r.left + 90;
        baner.top = r.top + sBaner.cy + 28;
        baner.right = 460;
        baner.bottom = r.bottom;
        lfHeight = -MulDiv( 8, GetDeviceCaps( MemDC, LOGPIXELSY), 72 );
        hf = CreateFont( lfHeight, 0, 0, 0, FW_BOLD, 0, 0, 0, 0, 0, 0, 0, 0, L"Arial Black" );
        SetTextColor( MemDC, RGB( 0, 0, 0 ) );
        hfOld = (HFONT)SelectObject( MemDC, hf ); // needed for proper cleanup
        DrawTextEx( MemDC, L"УПРАВА ГРАДА БЕОГРАДА\nСЕКРЕТАРИЈАТ ЗА КОМУНАЛНЕ И СТАМБЕНЕ ПОСЛОВЕ\nУПРАВА ЗА ЕНЕРГЕТИКУ",
	        wcslen(L"УПРАВА ГРАДА БЕОГРАДА\nСЕКРЕТАРИЈАТ ЗА КОМУНАЛНЕ И СТАМБЕНЕ ПОСЛОВЕ\nУПРАВА ЗА ЕНЕРГЕТИКУ"), 
			&baner, DT_CENTER | DT_NOCLIP | DT_WORDBREAK, 0 );
/*************************** top right text *************************/
// position it properly
        baner.top = r.top + sBaner.cy + 28;
        baner.left = r.right - 350;
        baner.right = r.right - 100;
        baner.bottom = r.bottom;
        DrawTextEx( MemDC, L"УНИВЕРЗИТЕТ У БЕОГРАДУ\nРУДАРСКО ГЕОЛОШКИ ФАКУЛТЕТ\nДЕПАРТМАН ЗА ХИДРОГЕОЛОГИЈУ",
			wcslen(L"УНИВЕРЗИТЕТ У БЕОГРАДУ\nРУДАРСКО ГЕОЛОШКИ ФАКУЛТЕТ\nДЕПАРТМАН ЗА ХИДРОГЕОЛОГИЈУ"), 
			&baner, DT_CENTER | DT_VCENTER | DT_NOCLIP | DT_WORDBREAK, 0 );
        SelectObject( MemDC, hfOld ); // proper cleanup
        DeleteObject( hf );
//========= draw right text in status bar =============//
        lfHeight = -MulDiv( 8, GetDeviceCaps( MemDC, LOGPIXELSY), 72 );
        hf = CreateFont( lfHeight, 0, 0, 0, FW_BOLD, TRUE, 0, 0, 0, 0, 0, 0, 0, L"Arial Black" );
        hfOld = (HFONT)SelectObject( MemDC, hf ); // needed for proper cleanup
        GetTextExtentPoint32( MemDC, L"ЦЕНТАР ЗА ОБНОВЉИВЕ ВОДНЕ ЕНЕРГЕТСКЕ РЕСУРСЕ",
			wcslen(L"ЦЕНТАР ЗА ОБНОВЉИВЕ ВОДНЕ ЕНЕРГЕТСКЕ РЕСУРСЕ"), &sBaner );
// position it properly
        rect.bottom = r.bottom;
        rect.right = r.left + sBaner.cx + 30;
        rect.left = r.left + 30;
        rect.top = r.bottom - r.top - 30;
// draw it to the back buffer
        DrawTextEx( MemDC, L"РУДАРСКО ГЕОЛОШКИ ФАКУЛТЕТ\nЦЕНТАР ЗА ОБНОВЉИВЕ ВОДНЕ ЕНЕРГЕТСКЕ РЕСУРСЕ",
                wcslen(L"РУДАРСКО ГЕОЛОШКИ ФАКУЛТЕТ\nЦЕНТАР ЗА ОБНОВЉИВЕ ВОДНЕ ЕНЕРГЕТСКЕ РЕСУРСЕ"), 
                &rect, DT_CENTER | DT_VCENTER | DT_NOCLIP | DT_WORDBREAK, 0 );
        SelectObject( MemDC, hfOld ); // proper cleanup
        DeleteObject( hf );
//============== right text in the status bar ==================//
        lfHeight = -MulDiv( 10, GetDeviceCaps( MemDC, LOGPIXELSY), 72 );
        hf = CreateFont( lfHeight, 0, 0, 0, FW_BOLD, TRUE, 0, 0, 0, 0, 0, 0, 0, L"Arial" );
        hfOld = (HFONT)SelectObject( MemDC, hf ); // needed for proper cleanup
        GetTextExtentPoint32( MemDC, L" Дејан Миленић & Ана Врањеш © 2013 сва права задржана",
                wcslen(L" Дејан Миленић & Ана Врањеш © 2013 сва права задржана"), &sBaner );
// position it properly
        rect.bottom = r.bottom;
        rect.right = r.right - 10;
        rect.left = r.right - r.left - sBaner.cx - 10;
        rect.top = r.bottom - r.top - sBaner.cy;
// draw it to the back buffer
        DrawTextEx( MemDC, L" Дејан Миленић & Ана Врањеш © 2013 сва права задржана",
			wcslen(L" Дејан Миленић & Ана Врањеш © 2013 сва права задржана"), 
			&rect, DT_CENTER | DT_VCENTER | DT_NOCLIP | DT_WORDBREAK | DT_NOPREFIX, 0 );
        // perform proper cleanup
        SelectObject( MemDC, hfOld );
        DeleteObject(hf);
/****************** draw static control's background ******************/
//=============== top left blue static control ================//
//position it properly
        rect.left = ( 3  * ( r.right - r.left ) / 4 - 340 ) / 3;
        rect.top = 230 + ( r.bottom - r.top - 450 ) / 3;
        rect.right = 150 + ( 3  * ( r.right - r.left ) / 4 - 340 ) / 3;
        rect.bottom = 270 + ( r.bottom - r.top - 450 ) / 3;
        // draw text
        // set font size below via function's first argument 
        lfHeight = -MulDiv( 8, GetDeviceCaps( MemDC, LOGPIXELSY ), 72);
        hf = CreateFont( lfHeight, 0, 0, 0, FW_BOLD, 0, 0, 0, 0, 0, 0, 0, 0, L"Arial Black");
        hfOld = (HFONT)SelectObject( MemDC, hf );
        DrawTextEx( MemDC, L"УНОС ПОДАТАКА", wcslen(L"УНОС ПОДАТАКА"),
                &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_WORDBREAK, 0 );
//================= top right blue static control =====================//
//position it properly
        rect.left = 150 + 2 * ( 3  * ( r.right - r.left ) / 4 - 340 ) / 3;
        rect.top = 230 + ( r.bottom - r.top - 450 ) / 3;
        rect.right = 300 + 2 * ( 3  * ( r.right - r.left ) / 4 - 340 ) / 3;
        rect.bottom = 270 + ( r.bottom - r.top - 450 ) / 3;
// draw text
        DrawTextEx( MemDC, L"ПРЕГЛЕД ПОДАТАКА", wcslen(L"ПРЕГЛЕД ПОДАТАКА"),
	        &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_WORDBREAK, 0 );
//================= bottom left blue static control =====================//
//position it properly
        rect.left = ( 3  * ( r.right - r.left ) / 4 - 340 ) / 3;
        rect.top = 380 + 2 * ( r.bottom - r.top - 450 ) / 3;
        rect.right = 150 + ( 3  * ( r.right - r.left ) / 4 - 340 ) / 3;
        rect.bottom = 420 + 2 * ( r.bottom - r.top - 450 ) / 3;
// draw text
        DrawTextEx( MemDC, L"ИЗВЕШТАЈ", wcslen(L"ИЗВЕШТАЈ"),
        &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_WORDBREAK, 0 );
//================= bottom right blue static control =====================//
//position it properly
        rect.left = 150 + 2 * ( 3  * ( r.right - r.left ) / 4 - 340 ) / 3;
        rect.top = 380 + 2 * ( r.bottom - r.top - 450 ) / 3;
        rect.right = 300 + 2 * ( 3  * ( r.right - r.left ) / 4 - 340 ) / 3;
        rect.bottom = 420 + 2 * ( r.bottom - r.top - 450 ) / 3;
        // draw text
        DrawTextEx( MemDC, L"ПРЕТРАГА", wcslen(L"ПРЕТРАГА"),
        &rect, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_WORDBREAK, 0 );
        SelectObject( MemDC, hfOld );
        DeleteObject(hf);
//================ text for orange static controls =============//
// first one
        rect.left = 3 * ( r.right - r.left ) / 4 + 10;
        rect.top = r.top + 160;
        rect.right = r.right - r.top - 50;
        rect.bottom = r.top + 180;
 //============= draw text ======//
        lfHeight = -MulDiv( 10, GetDeviceCaps( MemDC, LOGPIXELSY ), 72);
        hf = CreateFont(lfHeight, 0, 0, 0, FW_BOLD, 0, 0, 0, 0, 0, 0, 0, 0,L"Arial Unicode MS");
        hfOld = (HFONT)SelectObject( MemDC, hf );
        DrawTextEx( MemDC, L"ИНФОРМАЦИЈЕ", wcslen(L"ИНФОРМАЦИЈЕ"), &rect, 
                DT_VCENTER | DT_LEFT | DT_SINGLELINE, 0 );
// second one
        rect.left = 3 * ( r.right - r.left ) / 4 + 10;
        rect.top = r.top + 200;
        rect.bottom = r.top + 220;
//====== draw text ======//
        DrawTextEx( MemDC, L"ПОМОЋ", wcslen(L"ПОМОЋ"), &rect, 
		        DT_VCENTER | DT_LEFT | DT_SINGLELINE, 0 );
// third one
        rect.left = 3 * ( r.right - r.left ) / 4 + 10;
        rect.top = r.top + 240;
        rect.bottom = r.top + 260;
        //====== draw text ======//
        DrawTextEx( MemDC, L"КОРИСНИ ЛИНКОВИ", wcslen(L"КОРИСНИ ЛИНКОВИ"), &rect, 
                DT_VCENTER | DT_LEFT | DT_SINGLELINE, 0 );
        // font is no longer needed, so do cleanup
        SelectObject( MemDC, hfOld );
        DeleteObject(hf);
}
 /*  
void drawImages( HDC hdc, CDC* MemDC, RECT r ) 
{
        HDC hdcMemImg = CreateCompatibleDC(hdc); // back buffer for bitmaps
        RECT rect = { 0, 0, 0, 0 }; // needed for proper positioning
        //******************* top middle logo ******************
        BITMAP b;
        memset( &b, 0 , sizeof(BITMAP) );
        GetObject( bmpSimbol, sizeof(BITMAP), &b );
        // needed for proper cleanup
        // ( we select a bitmap from resource file )
        HBITMAP oldBmp = (HBITMAP)SelectObject( hdcMemImg, bmpSimbol );
        // draw bitmap to the back buffer
     TransparentBlt( MemDC, ( r.right - r.left - 64 ) / 2, r.top + 45, 64, 64, 
              hdcMemImg, 0, 0, b.bmWidth, b.bmHeight, RGB( 0, 0, 0) );

		TransparentBlt(int xDest, int yDest, int nDestWidth,
			int nDestHeight, CDC* pSrcDC, int xSrc, int ySrc, int nSrcWidth,
			int nSrcHeight, UINT crTransparent)
        SelectObject( hdcMemImg, oldBmp ); // proper cleanup

//=============== top left blue static control ================//
//position it properly
        rect.left = ( 3  * ( r.right - r.left ) / 4 - 340 ) / 3;
        rect.top = 120 + ( r.bottom - r.top - 450 ) / 3;
        rect.right = 150 + ( 3  * ( r.right - r.left ) / 4 - 340 ) / 3;
        rect.bottom = 270 + ( r.bottom - r.top - 450 ) / 3;
        memset( &b, 0, sizeof(BITMAP) );
        GetObject( bmpBTN1, sizeof(BITMAP), &b );
        oldBmp = (HBITMAP)SelectObject( hdcMemImg, bmpBTN1 );
        // draw bitmap on back buffer
        TransparentBlt( MemDC, rect.left + 20, rect.top + 10, rect.right - rect.left - 30, 
                rect.bottom - rect.top - 40, 
                hdcMemImg, 0, 0, b.bmWidth, b.bmHeight, RGB( 0, 0, 0 ) );
        SelectObject( hdcMemImg, oldBmp );
//================= top right blue static control =====================//
//position it properly
        rect.left = 150 + 2 * ( 3  * ( r.right - r.left ) / 4 - 340 ) / 3;
        rect.top = 120 + ( r.bottom - r.top - 450 ) / 3;
        rect.right = 300 + 2 * ( 3  * ( r.right - r.left ) / 4 - 340 ) / 3;
        rect.bottom = 270 + ( r.bottom - r.top - 450 ) / 3;
        memset( &b, 0, sizeof(BITMAP) );
        GetObject( bmpBTN2, sizeof(BITMAP), &b );
        oldBmp = (HBITMAP)SelectObject( hdcMemImg, bmpBTN2 );
        // draw bitmap on back buffer
        TransparentBlt( MemDC, rect.left + 15, rect.top + 10, rect.right - rect.left - 30, 
                rect.bottom - rect.top - 40, hdcMemImg, 0, 0, b.bmWidth, b.bmHeight, RGB( 255, 0, 255 ) );
        SelectObject( hdcMemImg, oldBmp );
//================= bottom left blue static control =====================//
//position it properly
        rect.left = ( 3  * ( r.right - r.left ) / 4 - 340 ) / 3;
        rect.top = 270 + 2 * ( r.bottom - r.top - 450 ) / 3;
        rect.right = 150 + ( 3  * ( r.right - r.left ) / 4 - 340 ) / 3;
        rect.bottom = 420 + 2 * ( r.bottom - r.top - 450 ) / 3;
        memset( &b, 0, sizeof(BITMAP) );
        GetObject( bmpBTN3, sizeof(BITMAP), &b );
        oldBmp = (HBITMAP)SelectObject( hdcMemImg, bmpBTN3 );
        // draw left bitmap on back buffer
        TransparentBlt( MemDC, rect.left + 5, rect.top + 20, ( rect.right - rect.left) / 2, 
	         rect.bottom - rect.top - 60, hdcMemImg, 0, 0, b.bmWidth, b.bmHeight, RGB( 0, 0, 0 ) );
        SelectObject( hdcMemImg, oldBmp );
        // draw right bitmap on back buffer
        memset( &b, 0 , sizeof(BITMAP) );
        GetObject( bmpBTN3a, sizeof(BITMAP), &b );
        oldBmp = (HBITMAP)SelectObject( hdcMemImg, bmpBTN3a );
        TransparentBlt( MemDC, rect.left + ( rect.right - rect.left) / 2 + 5, rect.top + 20, 
                ( rect.right - rect.left) / 2 - 5, rect.bottom - rect.top - 60, 
                hdcMemImg, 0, 0, b.bmWidth, b.bmHeight, RGB( 0, 0, 0 ) );
        SelectObject( hdcMemImg, oldBmp );
        //position it properly
        rect.left = 150 + 2 * ( 3  * ( r.right - r.left ) / 4 - 340 ) / 3;
        rect.top = 270 + 2 * ( r.bottom - r.top - 450 ) / 3;
        rect.right = 300 + 2 * ( 3  * ( r.right - r.left ) / 4 - 340 ) / 3;
        rect.bottom = 420 + 2 * ( r.bottom - r.top - 450 ) / 3;
        memset( &b, 0, sizeof(BITMAP) );
        GetObject( bmpBTN4, sizeof(BITMAP), &b );
        oldBmp = (HBITMAP)SelectObject( hdcMemImg, bmpBTN4 );
        // draw bitmap on back buffer
        TransparentBlt( MemDC, rect.left + 25, rect.top + 10, rect.right - rect.left - 50, 
         rect.bottom - rect.top - 40, hdcMemImg, 0, 0, b.bmWidth, b.bmHeight, RGB( 0, 0, 0 ) );
        SelectObject( hdcMemImg, oldBmp );
        //================= static controls on orange panel ==================//
        // first one
        rect.left = 3 * ( r.right - r.left ) / 4 - 30;
        rect.top = r.top + 150;
        rect.right = r.right - r.top - 50;
        rect.bottom = r.top + 180;
        memset( &b, 0, sizeof(BITMAP) );
        GetObject( bmpInfo, sizeof(BITMAP), &b );
        oldBmp = (HBITMAP)SelectObject( hdcMemImg, bmpInfo );
        // draw bitmap on back buffer
        TransparentBlt( MemDC, rect.left, rect.top, 30, 30, hdcMemImg, 0, 0, 
                b.bmWidth, b.bmHeight, RGB( 255, 163, 94 ) );
        SelectObject( hdcMemImg, oldBmp );
        // second one
        rect.left = 3 * ( r.right - r.left ) / 4 - 30;
        rect.top = r.top + 190;
        rect.bottom = r.top + 220;
        //=============== draw bitmap =============//
        memset( &b, 0, sizeof(BITMAP) );
        GetObject( bmpHelp, sizeof(BITMAP), &b );
        oldBmp = (HBITMAP)SelectObject( hdcMemImg, bmpHelp );
        // draw bitmap on back buffer
        TransparentBlt( MemDC, rect.left, rect.top, 30, 30, hdcMemImg, 0, 0, 
                b.bmWidth, b.bmHeight, RGB( 255, 163, 94 ) );
        SelectObject( hdcMemImg, oldBmp );
        // third one
        rect.left = 3 * ( r.right - r.left ) / 4 - 30;
        rect.top = r.top + 230;
        rect.bottom = r.top + 260;
//=============== draw bitmap =============//
        memset( &b, 0, sizeof(BITMAP) );
        GetObject( bmpLink, sizeof(BITMAP), &b );
        oldBmp = (HBITMAP)SelectObject( hdcMemImg, bmpLink );
        // draw bitmap on back buffer
        TransparentBlt( MemDC, rect.left, rect.top, 30, 30, hdcMemImg, 0, 0, 
                b.bmWidth, b.bmHeight, RGB( 255, 163, 94 ) );
        SelectObject( hdcMemImg, oldBmp );
 //========= draw EMF and PNG files =========//
       Graphics graphics( MemDC );
		/******* fourth orange static control with the map ( EMF file ) ********
     // proper positioning
       rect.top = r.top + 270;
       rect.bottom = r.bottom - 60;
	   rect.left = 3 * ( r.right - r.left ) / 4 - 30;
//============= aspect ratio ================//
       UINT o_height = btn5->GetHeight(), o_width =  btn5->GetWidth();
       float scale = 0.5;  int mapPosX, mapPosY;
	   scale = (float)( rect.right - rect.left ) / o_width;
       if( (float)( rect.bottom - rect.top ) / o_height  <  scale )
	   {
            scale = (float)( rect.bottom - rect.top ) / o_height;
            int marginX = ( rect.right - rect.left ) - (int)( o_width * scale );
			int marginY = ( rect.bottom - rect.top ) - (int)( o_height * scale );
			marginX /= 2;  marginY /= 2; mapPosX = rect.left + marginX; 
			mapPosY = rect.top + marginY; 
			graphics.DrawImage( btn5, mapPosX, mapPosY, (int)( o_width * scale ),
					(int)( o_height * scale ) );
/******************** top left logo ( PNG file ) *******************
            o_height = image->GetHeight();
			o_width = image->GetWidth();
            graphics.DrawImage( image, r.left + 5, r.top + 10, o_width, o_height );
/******************** top right logo ( PNG file ) ******************
			o_height = image1->GetHeight();
            o_width = image1->GetWidth();
			graphics.DrawImage( image1, r.right - r.left - 90, r.top + 10, o_width, o_height );
        }
		DeleteDC(hdcMemImg); // release memory DC 
}
*/
void OnDraw( CDC* pDC) 
{
	RECT r; HWND hwnd;
    GetClientRect(hwnd, &r);
    CreateCompatibleDC(pDC->m_hDC); // back buffer
	CBitmap bmp = CreateCompatibleBitmap(pDC->m_hDC, r.right - r.left, r.bottom - r.top),
	CBitmap oldBmp = SelectObject(&bmp); // needed for cleanup
/*************** draw banner ******************/
// position it properly at the top
        RECT rect;
        rect.left = r.left;
        rect.top = r.top;
        rect.right = r.right;
        rect.bottom = 120;
// draw background for middle part of the window
        drawBackground( pDC, r );
//draw header with grid lines
        drawHeader( pDC, rect, hbPozadina );
// draw "status bar"
        drawFooter( pDC, r, RGB( 0x48, 0xAC, 0xC6), RGB( 0x31, 0x83, 0x99 ) );
/****************** draw static control's background ******************/
//=============== top left static control ================//
//position it properly
        rect.left = ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
        rect.top = 120 + ( r.bottom - r.top - 450 ) / 3;
        rect.right = 150 + ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
        rect.bottom = 270 + ( r.bottom - r.top - 450 ) / 3;
// draw gradient button
        FillButton( pDC, rect, BlueFrame );
//================= top right static control =====================//
//position it properly
        rect.left = 150 + 2 * ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
        rect.top = 120 + ( r.bottom - r.top - 450 ) / 3;
        rect.right = 300 + 2 * ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
        rect.bottom = 270 + ( r.bottom - r.top - 450 ) / 3;
        // draw gradient button
        FillButton( pDC, rect, BlueFrame );
//================= bottom left static control =====================//
//position it properly
        rect.left = ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
        rect.top = 270 + 2 * ( r.bottom - r.top - 450 ) / 3;
        rect.right = 150 + ( 3 * ( r.right - r.left ) / 4 - 340 ) / 3;
        rect.bottom = 420 + 2 * ( r.bottom - r.top - 450 ) / 3;
// draw gradient button
        FillButton( pDC, rect, BlueFrame );
//================= bottom right static control =====================//
//position it properly
        rect.left = 150 + 2 * ( 3  * ( r.right - r.left ) / 4 - 340 ) / 3;
		rect.top = 270 + 2 * ( r.bottom - r.top - 450 ) / 3;
		rect.right = 300 + 2 * ( 3  * ( r.right - r.left ) / 4 - 340 ) / 3;
		rect.bottom = 420 + 2 * ( r.bottom - r.top - 450 ) / 3;
// draw gradient button
        FillButton( pDC, rect, BlueFrame );
//======================== draw orange panel =================//
//position it properly
        rect.left = 3 * ( r.right - r.left ) / 4 - 40;
        rect.top = r.top + 140;
        rect.right = rect.left + ( r.right - r.left ) / 4;
        rect.bottom = rect.top + ( r.bottom - r.top - 190 );
        drawOrangePanel( pDC, rect, RGB( 0xFF, 0xC8, 0xAA ), RGB( 0xFF, 0x96, 0x48 ) );
        // draw all the text
        drawStrings( pDC, r );
        // draw all the bitmaps and EMF files
        drawImages( hdc, MemDC, r );
        /****************** draw back buffer on the screen DC *****************/
        BitBlt(0, 0, r.right - r.left, r.bottom - r.top, pDC, 0, 0, SRCCOPY );
        /************** cleanup *******************/
        SelectObject(oldBmp );
        DeleteObject(bmp); // compatible bitmap for MemDC
}

// WinMain's procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
        switch(msg)
        {
        case WM_CREATE:
			{
				image = Image::FromFile(L".\\resources\\BG.png"), // upper left logo
                image1 = Image::FromFile(L".\\resources\\RGF.png"); // upper right logo
				btn5 = Image::FromFile(L".\\resources\\BTN5.emf"); // map in the bottom of the orange button
      // load gray background brush for the top banner
                hbPozadina = CreateSolidBrush( RGB( 230, 230, 230 ) );
      // load left icon in the status bar
                hiAdmin = LoadIcon( hInst, MAKEINTRESOURCE(IDI_ICON2) );
      // bitmaps for static controls
                bmpBTN1 = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP1) );
                bmpBTN2 = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP10) );
    /** these two bitmaps make one image for the bottom right blue static control **/
                bmpBTN3 = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP3) );
                bmpBTN3a = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP5) );
//**********************************************************************//
                bmpBTN4 = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP4) );
                bmpSimbol = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP16) );
                bmpInfo = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP6) );
				bmpLink = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP7) );
				bmpHelp = LoadBitmap( hInst, MAKEINTRESOURCE(IDB_BITMAP8) );
//******** brushes ***********//
// brush for orange panel that holds 3 static controls and a map
				hbr = CreateSolidBrush( RGB( 255, 163, 94 ) ); 
// blue frame for blue static controls
                BlueFrame = CreateSolidBrush( RGB(79, 129, 189) ); 
/*******************************************/
// get rectangle dimensions of the main window
				RECT rec;
				GetClientRect( hwnd, &rec );
  /******* main window's static controls ******/
// top left
				HWND hsUnosPodataka = CreateWindowEx( 0, L"Static", L"", WS_VISIBLE | WS_CHILD | SS_NOTIFY, 
							( 3  * ( rec.right - rec.left ) / 4 - 340 ) / 3, 
						    120 + ( rec.bottom - rec.top - 450 ) / 3, 
						    150, 150, hwnd, (HMENU)4000, hInst, 0);
// top right
				HWND hsPregledPodataka = CreateWindowEx( 0, L"Static", L"",  WS_VISIBLE | WS_CHILD | SS_NOTIFY,
                            150 + 2 * ( 3  * ( rec.right - rec.left ) / 4 - 340 ) / 3, 
						    120 + ( rec.bottom - rec.top - 450 ) / 3, 
						    150, 150, hwnd, (HMENU)4001, hInst, 0);
// bottom left
				HWND hsIzvestaj = CreateWindowEx(0, L"Static", L"", WS_VISIBLE | WS_CHILD | SS_NOTIFY, 
	                        ( 3  * ( rec.right - rec.left ) / 4 - 340 ) / 3, 
						    270 + 2 * ( rec.bottom - rec.top - 450 ) / 3, 
						    150, 150, hwnd, (HMENU)4002, hInst, 0);
// bottom right
				HWND hsPretraga = CreateWindowEx(0, L"Static", L"", WS_VISIBLE | WS_CHILD | SS_NOTIFY,
                            150 + 2 * ( 3  * ( rec.right - rec.left ) / 4 - 340 ) / 3, 
                            270 + 2 * ( rec.bottom - rec.top - 450 ) / 3,
                            150, 150, hwnd, (HMENU)4003, hInst, 0);
//============= static controls on the orange panel ==============//
// first one from the top
				HWND hsInfoInfo = CreateWindowEx(0, L"Static", L"", WS_VISIBLE | WS_CHILD | SS_NOTIFY, 
                            3 * ( rec.right - rec.left ) / 4 - 30, rec.top + 150, 
							( rec.right - rec.left ) / 4 - 20, 30, hwnd, (HMENU)4007, hInst, 0);
// second one from the top
				HWND hsInfoHelp = CreateWindowEx(0, L"Static", L"", WS_VISIBLE | WS_CHILD | SS_NOTIFY,
                            3 * ( rec.right - rec.left ) / 4 - 30, rec.top + 190, 
						    ( rec.right - rec.left ) / 4 - 20, 30, hwnd, (HMENU)4009, hInst, 0);
// third one from the top
				HWND hsInfoLink = CreateWindowEx(0, L"Static", L"", WS_VISIBLE | WS_CHILD | SS_NOTIFY, 
                            3 * ( rec.right - rec.left ) / 4 - 30, rec.top + 230, 
						    ( rec.right - rec.left ) / 4 - 20, 30, hwnd, (HMENU)4008, hInst, 0);
// fourth one-it will contain a map
				HWND hsInfoKarta = CreateWindowEx(0, L"Static", L"", WS_VISIBLE | WS_CHILD | SS_NOTIFY,
	                        3 * ( rec.right - rec.left ) / 4 - 30, rec.top + 270, 
						    ( rec.right - rec.left ) / 4 - 20, rec.bottom - rec.top - 330,
						    hwnd, (HMENU)4010, hInst, 0);
			}
			return (LRESULT)0;
		case WM_COMMAND:
			{
				switch (LOWORD(wParam))
				{
				case 4000:
				case 4001:
				case 4002:
				case 4003:
				case 4007:
				case 4008:
				case 4009:
				case 4010:
					MessageBeep(MB_ICONEXCLAMATION);
					break;
				default:
					return DefWindowProc(hwnd, msg, wParam, lParam);
				}
				break;
			}
        case WM_ERASEBKGND:
			return (LRESULT)1; // so we avoid flicker ( all painting is in WM_PAINT )
        case WM_PAINT:
			{
            // paint the picture
				CDC* pDC = GetWindowDC(hwnd);
				OnDraw(pDC);
            }
			return (LRESULT)0;
        case WM_SIZE:
            {
	            RECT rec;
                GetClientRect( hwnd, &rec );
                SetWindowPos( GetDlgItem( hwnd, 4000 ), NULL, ( 3  * ( rec.right - rec.left ) / 4 - 340 ) / 3, 
                120 + ( rec.bottom - rec.top - 450 ) / 3, 150, 150, 
                SWP_NOZORDER | SWP_NOCOPYBITS );
                SetWindowPos( GetDlgItem( hwnd, 4001 ), NULL, 150 + 2 * ( 3  * ( rec.right - rec.left ) / 4 - 340 ) / 3, 
							120 + ( rec.bottom - rec.top - 450 ) / 3, 150, 150, SWP_NOZORDER | SWP_NOCOPYBITS);
                SetWindowPos( GetDlgItem( hwnd, 4002 ), NULL, ( 3  * ( rec.right - rec.left ) / 4 - 340 ) / 3, 
				            270 + 2 * ( rec.bottom - rec.top - 450 ) / 3, 150, 150, SWP_NOZORDER | SWP_NOCOPYBITS );
                SetWindowPos( GetDlgItem( hwnd, 4003 ), NULL, 150 + 2 * ( 3  * ( rec.right - rec.left ) / 4 - 340 ) / 3, 
				            270 + 2 * ( rec.bottom - rec.top - 450 ) / 3, 150, 150, SWP_NOZORDER | SWP_NOCOPYBITS );
                SetWindowPos( GetDlgItem( hwnd, 4007 ), NULL, 3 * ( rec.right - rec.left ) / 4 - 30, rec.top + 150, 
							( rec.right - rec.left ) / 4 - 20, 30, SWP_NOZORDER | SWP_NOCOPYBITS );
                SetWindowPos( GetDlgItem( hwnd, 4008 ), NULL, 3 * ( rec.right - rec.left ) / 4 - 30, rec.top + 190, 
							( rec.right - rec.left ) / 4 - 20, 30, SWP_NOZORDER | SWP_NOCOPYBITS );
                SetWindowPos( GetDlgItem( hwnd, 4009 ), NULL, 3 * ( rec.right - rec.left ) / 4 - 30, rec.top + 230, 
							( rec.right - rec.left ) / 4 - 20, 30, SWP_NOZORDER | SWP_NOCOPYBITS );
                SetWindowPos( GetDlgItem( hwnd, 4010 ), NULL, 3 * ( rec.right - rec.left ) / 4 - 30, rec.top + 270, 
							( rec.right - rec.left ) / 4 - 20, rec.bottom - rec.top - 330, SWP_NOZORDER | SWP_NOCOPYBITS );
				InvalidateRect( hwnd, NULL, FALSE ); 
            }
			return (LRESULT)0;
		case WM_CTLCOLORSTATIC:
            return (LRESULT)( (HBRUSH)GetStockObject(NULL_BRUSH) );
		case WM_CLOSE:
			{
                DeleteObject(bmpSimbol);
                DeleteObject(bmpBTN1);
                DeleteObject(bmpBTN2);
                DeleteObject(bmpBTN3);
                DeleteObject(bmpBTN4);
                DeleteObject(bmpInfo);
                DeleteObject(bmpLink);
                DeleteObject(bmpHelp);
                DestroyIcon(hIcon);
                DestroyIcon(hiAdmin);
                DeleteObject(hbPozadina);
                DeleteObject(hbr);
                DeleteObject(BlueFrame);
                delete image;
                delete image1;
                delete btn5;
                DestroyWindow(hwnd);
			}
			return (LRESULT)0;
		case WM_DESTROY:
			{
                PostQuitMessage(0);
			}
            return (LRESULT)0;
        default:
		return DefWindowProc(hwnd, msg, wParam, lParam);
        }
        return 0;
}
// WinMain
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// store hInstance in global variable for later use
	hInst = hInstance; // load main icon
    hIcon = LoadIcon( hInst, MAKEINTRESOURCE(IDI_ICON1));
    WNDCLASSEX wc;  HWND hwnd; MSG Msg;
/*********** variables for GDI+ initialization *****************/
    GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
/************** Initialize GDI+. *************************/
    GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
/*************** finished GDI+ initialisation ********************/
// initialize common controls
    INITCOMMONCONTROLSEX iccex;
	iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
	iccex.dwICC = ICC_STANDARD_CLASSES ;
	InitCommonControlsEx(&iccex);
// register main window class
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = 0;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInst;
    wc.hIcon = hIcon;
	wc.hCursor = LoadCursor( NULL, IDC_ARROW );
    wc.hbrBackground = (HBRUSH)GetStockObject( WHITE_BRUSH );
    wc.lpszMenuName = NULL;
    wc.lpszClassName = L"Main_Window";
    wc.hIconSm = hIcon;
    if(!RegisterClassEx(&wc))
    {
	     MessageBox(NULL, L"Window Registration Failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK);
         return 0;
	}
     // create main window
    hwnd = CreateWindowEx( 0, L"Main_Window", L"Геотермист", WS_OVERLAPPEDWINDOW,
		( GetSystemMetrics(SM_CXMAXIMIZED) - 1020 ) / 2, 
		( GetSystemMetrics(SM_CYMAXIMIZED) - 600 ) / 2, 
		1020, 600, NULL, NULL, hInstance, 0 );
    if(hwnd == NULL)
	{
		MessageBox(NULL, L"Window creation failed!", L"Error!", MB_ICONEXCLAMATION | MB_OK);
        return 0; 
	}
	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);
	while(GetMessage(&Msg, NULL, 0, 0) > 0)
	{
	    TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}
        // shutdownd GDI+
    GdiplusShutdown(gdiplusToken);
	return Msg.wParam;
}


</gdiplus.h></commctrl.h></windowsx.h></afxwin.h></windows.h>


这篇关于双缓冲故障(使用小型演示源代码更新)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆