例程实现的功能说明
1、主窗体采用POPUP样式,无标题栏、无菜单栏,适合工业类软件
2、按钮、标签使用自绘,实现透明样式,可以实现灵活的样式设计,更具设计感
按钮重绘函数:OnDrawItem()
按钮样式设定:WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | BS_OWNERDRAW
消息处理函数的设定:
case WM_DRAWITEM:
OnDrawItem(hWnd, message, wParam, lParam);
break;
case WM_CTLCOLORBTN:
return (LRESULT)(HBRUSH)GetStockObject(NULL_BRUSH);
break;
标签重回函数:DrawStatic()
case WM_CTLCOLORSTATIC:
return DrawStatic(hWnd, message, wParam, lParam);
break;
3、整个UI进行了独立设计,导出了函数,可以在主程序使用
4、实现了全局变量的导入,减少了局部变量的使用
5、使用pBITMAPINFO结构体实现了图形图像的灵活绘制与显示
6、根据窗口尺寸,绘制了几个RGB格式位图图像,显示到了指定窗口上
7、实现了状态栏文本消息的显示,当消息不需要刷新时,不进行显示的刷新操作
状态栏文本显示函数:SetStatusBarText()
8、右侧面板预留了几个空白的区域用于应用系统的扩展
9、按钮和右侧预留的功能子窗口的创建使用了数组,通过for循环创建
10、按钮和右侧预留的功能子窗口使用了字符串数组,循环加载文本信息
11、状态栏子项的宽度使用百分比进行自动计算
12、按钮的菜单ID 使用变量进行自动计算,只需要定义首个按钮的ID即可
13、开放给用户的图像显示窗口封装了函数
显示图像缓冲区数据到窗口的函数:show_imageBuffer()
14、使用F10键或ESC、退出按钮均可以退出系统
15、创建了三种字体供系统使用
以下是UI的样式
以下是代码:
UI.h
#pragma once
#include <windows.h>
#include <stdio.h>
#include <CommCtrl.h> //SysListView32控件调用的库
#pragma comment(lib,"comctl32.lib")
// 使用Windows视觉效果
#if defined _M_IX86
#pragma comment(linker,"/manifestdependency:\"type='win32' "\
" name='Microsoft.Windows.Common-Controls' "\
" version='6.0.0.0' processorArchitecture='x86' "\
"publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_IA64
#pragma comment(linker,"/manifestdependency:\"type='win32'"\
" name='Microsoft.Windows.Common-Controls' "\
"version='6.0.0.0' processorArchitecture='ia64'"\
" publicKeyToken='6595b64144ccf1df' language='*'\"")
#elif defined _M_X64
#pragma comment(linker,"/manifestdependency:\"type='win32'"\
" name='Microsoft.Windows.Common-Controls'"\
" version='6.0.0.0' processorArchitecture='amd64'"\
" publicKeyToken='6595b64144ccf1df' language='*'\"")
#else
#pragma comment(linker,"/manifestdependency:\"type='win32'"\
" name='Microsoft.Windows.Common-Controls'"\
" version='6.0.0.0' processorArchitecture='*' "\
"publicKeyToken='6595b64144ccf1df' language='*'\"")
#endif
#define IDB_EXIT 3001 /* 顶部按钮组的起始编号 */
// 创建客户界面的函数
bool createUI(HWND hwndmain, WCHAR* szWindowClass, int width, int height, int* analySize, int* axis_size, int* img_size);
// 对Owner_Draw样式的按钮进行重新绘制
VOID OnDrawItem(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// 重绘static控件函数
INT_PTR DrawStatic(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
/*名称:SetStatusBarText
功能:设置状态栏某一格的文本
参数:hStatus状态栏句柄,i项,szString标题
*/
int SetStatusBarText(int i, char* szString);
// 将RGB位图缓冲数据显示到窗口
void show_imageBuffer(int id, HWND hWnd, unsigned char *src);
pch.h
// pch.h: 这是预编译标头文件。
// 下方列出的文件仅编译一次,提高了将来生成的生成性能。
// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。
#ifndef PCH_H
#define PCH_H
// 添加要在此处预编译的标头
#include "framework.h"
#endif //PCH_H
pch.cpp
// pch.cpp: 与预编译标头对应的源文件
#include "pch.h"
// 当使用预编译的头时,需要使用此源文件,编译才能成功。
UI.cpp
#include "pch.h"
#include "UI.h"
#define MAX_LOADSTRING 100
//#define BorderStyle // 显示边框
#if defined BorderStyle
#define staticStyle WS_CHILD | WS_VISIBLE | WS_BORDER
#define buttonStyle WS_CHILD | WS_VISIBLE | WS_BORDER | BS_DEFPUSHBUTTON | BS_OWNERDRAW
#else
#define staticStyle WS_CHILD | WS_VISIBLE
#define buttonStyle WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | BS_OWNERDRAW
#endif
COLORREF Caption_Color = RGB(0x00, 0x7A, 0xCC); // 应用系统标题字的文本颜色
COLORREF BtnOn_Color = RGB(0x32, 0xB9, 0x00); // 按钮按下时的文本颜色
COLORREF color_btn_normal = RGB(0x7A, 0xC0, 0xFF); // 按钮常态时的文本颜色
COLORREF color_imgWnd_text = RGB(0xFF, 0x0F, 0x00); // 图像窗口文本色
BITMAPINFO BMP_Analys;
unsigned char pFrameBuffer[3840 * 2160 * 3];
HDC hdc_image; /* 图像窗口的设备句柄 */
HWND hwndStatusBar; /* 状态栏窗口句柄 */
extern HWND hwnd_Analys;
HDC hdc_analys; /* 分析窗口的设备句柄 */
BITMAPINFO BMP_Axis = { 0 };
extern HWND hwnd_Axis_L; /* 左侧坐标轴窗口的句柄 */
extern HWND hwnd_Axis_R; /* 右侧坐标轴窗口的句柄 */
BITMAPINFO BMP_Image = { 0 };
extern HWND hwnd_Image; /* 坐标轴窗口的句柄 */
const int BarNum = 6;
char status_text[BarNum][256] = { "视觉传感器","输出状态", "专机连接状态","相机曝光时间", "相机帧率","处理时间" };
bool bRefreshChk = false;
BITMAPINFO* pBmpInf;
void show_imageBuffer(int id, HWND hWnd, unsigned char *src)
{
switch (id)
{
case 0:
pBmpInf = &BMP_Analys;
break;
case 1:
pBmpInf = &BMP_Axis;
break;
case 2:
pBmpInf = &BMP_Axis;
break;
case 3:
pBmpInf = &BMP_Image;
break;
default:
break;
}
int width = pBmpInf->bmiHeader.biWidth,
height = pBmpInf->bmiHeader.biHeight;
hdc_analys = GetDC(hWnd);
// 将数据送到窗口进行显示
StretchDIBits(hdc_analys,
0, 0, width, height,
0, 0, width, height,
src, pBmpInf, DIB_RGB_COLORS, SRCCOPY);
}
// 对Owner_Draw样式的按钮进行重新绘制
VOID OnDrawItem(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LPDRAWITEMSTRUCT pBtn = (LPDRAWITEMSTRUCT)lParam;
if (pBtn->CtlType == ODT_BUTTON) // 控件的类型是Owner-drawn button
{
if (pBtn->itemState & ODS_SELECTED)// 选中的状态
SetTextColor(pBtn->hDC, BtnOn_Color);
else
SetTextColor(pBtn->hDC, color_btn_normal);
TCHAR szName[256] = { 0 };
int nOldMode = SetBkMode(pBtn->hDC, TRANSPARENT); //设置文字背景模式
GetWindowText(pBtn->hwndItem, szName, 256); //取得按钮上面原来的文字
DrawText(pBtn->hDC, szName, (int)wcslen(szName), &pBtn->rcItem, DT_CENTER | DT_SINGLELINE | DT_VCENTER); //绘制位置
}
}
// 重绘static控件函数
INT_PTR DrawStatic(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
int i = GetWindowLong((HWND)lParam, GWL_ID);
switch (i)
{
case 0:
break;
default:
break;
}
SetTextColor((HDC)wParam, Caption_Color);
SetBkMode((HDC)wParam, TRANSPARENT);
return (INT_PTR)GetStockObject(NULL_BRUSH);
}
/* 名称:SetStatusBarText
功能:设置状态栏某一格的文本
参数:i序号,szString字符串指针
*/
int SetStatusBarText(int i, char* szString)
{
if ((i >= BarNum) || (hwndStatusBar == nullptr))
return 0;
// 比较两个字符串是否一致
int len_in = (int)strlen(szString), len_raw = (int)strlen(status_text[i]);
if ((len_in == len_raw) && bRefreshChk){
for (int j = 0; j < len_in; ++j){
if (szString[j] != status_text[i][j]) break;
else
if (j == (len_in - 1))
return 1; }}
memcpy_s(status_text[i], len_in, szString, len_in);
status_text[i][len_in] = 0;
len_in ++;
int nwLen = MultiByteToWideChar(CP_ACP, 0, status_text[i], len_in, NULL, 0);
LPWSTR lpszPath = new WCHAR[len_in];
MultiByteToWideChar(CP_ACP, 0, status_text[i], len_in, lpszPath, nwLen);
SendMessage(hwndStatusBar, SB_SETTEXT, (WPARAM)i, (LPARAM)lpszPath);
if(!bRefreshChk)
bRefreshChk = (i==(BarNum-1));
return 1;
}
/* HDC窗口显示字符串 */
void HDC_DrawText(int id_hdc, int x, int y, char* lpstr)
{
HDC hdc = ((id_hdc == 0) ? hdc_analys : hdc_image);
int len_in = (int)strlen(lpstr)+1;
int nwLen = MultiByteToWideChar(CP_ACP, 0, lpstr, len_in, NULL, 0);
LPWSTR lpszPath = new WCHAR[len_in];
MultiByteToWideChar(CP_ACP, 0, lpstr, len_in, lpszPath, nwLen);
TextOut(hdc, x, y, lpszPath, nwLen);
}
// 创建应用程序字体的函数
void createAppFont(HFONT* hFont, int mHeight, LOGFONT fontName)
{
LOGFONT LogFont;
memset(&LogFont, 0, sizeof(LOGFONT));
memcpy_s(&LogFont, sizeof(LOGFONT), &fontName, sizeof(LOGFONT));
LogFont.lfHeight = mHeight;
*hFont = CreateFontIndirect(&LogFont);
}
/* 名称:SetStatus函数
功能:将状态栏划分成多格
参数:hWnd主窗口句柄,hStatus状态栏句柄
*/
int SetStatus(HWND hWnd, HWND hStatus, int num, int* barwidth)
{
RECT WinRect;
GetClientRect(hWnd, &WinRect);
for (int i = 1; i < num - 1; i++)
barwidth[i] = barwidth[i - 1] + barwidth[i];
barwidth[num - 1] = WinRect.right - 2;
SendMessage(hStatus, SB_SETPARTS, (WPARAM)num, (LPARAM)barwidth);
return 1;
}
// 创建顶部控件组函数
void create_toppannel(HWND hparent,int mainwidth, int width, int height, int margin,int fontSize_caption, HFONT caption,HFONT hFont_Detail)
{
// LOGO的标签
int ctrlheight = height - margin * 3, Logo_width= ctrlheight+16, x0 = margin, y0 = margin;
HWND hwnd_Logo = CreateWindow(TEXT("static"), L"Logo", staticStyle,
x0, y0, Logo_width, ctrlheight, hparent, NULL, NULL, NULL);
SendMessage(hwnd_Logo, WM_SETFONT, (WPARAM)caption, 1);
// 标题的标签
x0 += margin + Logo_width, ctrlheight = fontSize_caption + margin * 2;
HWND hwnd_appCaption = CreateWindow(L"static", L"Wise Vision System", staticStyle,
x0 , y0, width, ctrlheight, hparent, NULL, NULL, NULL);
SendMessage(hwnd_appCaption, WM_SETFONT, (WPARAM)caption, 1);
// 子标题的标签
y0 += fontSize_caption + margin, ctrlheight = height - ctrlheight - margin * 2;
int detail_height = height - fontSize_caption - margin * 4;
HWND hwnd_appname = CreateWindow(L"static", L"Wise Vision System Ver 1.0", staticStyle,
x0, y0, width, ctrlheight, hparent, NULL, NULL, NULL);
SendMessage(hwnd_appname, WM_SETFONT, (WPARAM)hFont_Detail, 1);
// 右侧按钮
const int button_num = 8;
LPCWSTR ButtonText[button_num] = { L"退出系统",L"锁定系统", L"设备信息",L"参数设置", L"模板管理", L"录制视频",L"关闭输出",L"相机参数" };
int button_width = Logo_width;
x0 = mainwidth - button_width - margin * (button_num);
HWND hwnd_Button[button_num];
for (int i = 0; i < button_num; ++i){
hwnd_Button[i] = CreateWindowEx(NULL, L"button", ButtonText[i], buttonStyle,
x0, 0, button_width, height, hparent, (HMENU)(IDB_EXIT + i), NULL, NULL);
SendMessage(hwnd_Button[i], WM_SETFONT, (WPARAM)hFont_Detail, 1);
x0 -= button_width + margin * 10;}
}
// 创建右侧面板控件组函数
void createRightPannel(HWND hparent,int width,int height,int margin,HFONT font_detail)
{
/* 右侧子窗口的数量 */
const int children_num = 4;
/* 子窗口的标题 */
LPCWSTR pannelR_labeltext[children_num] = { L"控制参数",L"相机参数", L"算法参数",L"运行状态" };
/* 子窗口高度占容器高度的百分比 */
int children_height[children_num] = { 20,25,25,30 };/* 子窗口高度的百分比 */
/* 子窗口句柄数组 */
HWND hPanel_R[children_num];
int x0 = margin, y0 = margin, control_width = width - margin * 2;
for (int i = 0; i < children_num; ++i)
{
int control_height = children_height[i] * height / 100;
if (i == (children_num - 1))
control_height = height - y0 - margin;
hPanel_R[i] = CreateWindow(L"static", pannelR_labeltext[i], staticStyle,
x0, y0, control_width, control_height, hparent, NULL, NULL, NULL);
SendMessage(hPanel_R[i], WM_SETFONT, (WPARAM)font_detail, 1);
y0 += control_height + margin;
}
}
// 创建左侧面板控件组函数
void createLeftPannel(HWND hparent, int width, int height, int margin, HFONT font_normal,int* analys_size,int* ax_size, int* imgwnd_size)
{
int ctrl_width = width- margin*3,
ctrl_height = 128,
x0 = margin, y0 = height - ctrl_height;
analys_size[0] = ctrl_width -= (ctrl_width % 4);
analys_size[1] = ctrl_height -= (ctrl_height % 4);
// 底部分析数据窗口
hwnd_Analys = CreateWindow(L"static", L"动态分析数据窗口", staticStyle,
x0, y0, ctrl_width, ctrl_height, hparent, NULL, NULL, NULL);
SendMessage(hwnd_Analys, WM_SETFONT, (WPARAM)font_normal, 1);
BMP_Analys.bmiHeader.biWidth = ctrl_width;
BMP_Analys.bmiHeader.biHeight = ctrl_height;
BMP_Analys.bmiHeader.biBitCount = 24;
BMP_Analys.bmiHeader.biSize = 40;
BMP_Analys.bmiHeader.biPlanes = 1;
BMP_Analys.bmiHeader.biSizeImage = ctrl_width * ctrl_height * 3 + 1024;
BMP_Analys.bmiHeader.biXPelsPerMeter = 2834;
BMP_Analys.bmiHeader.biYPelsPerMeter = 2834;
BMP_Analys.bmiHeader.biCompression = 0;
BMP_Analys.bmiHeader.biClrUsed = 0;
BMP_Analys.bmiHeader.biClrImportant = 0;
for (int i = 0; i < 256; i++)
BMP_Analys.bmiColors[i] = { (unsigned char)i,(unsigned char)i,(unsigned char)i ,0 };
// 左侧坐标轴标记窗口
ctrl_width = 128;
ctrl_height = y0 - margin * 2, y0 = margin;
ax_size[0] = ctrl_width -= (ctrl_width % 4);
ax_size[1] = ctrl_height -= (ctrl_height % 4);
hwnd_Axis_L = CreateWindow(L"static", L"Y坐标轴_L", staticStyle,
x0, y0, ctrl_width, ctrl_height, hparent, NULL, NULL, NULL);
SendMessage(hwnd_Axis_L, WM_SETFONT, (WPARAM)font_normal, 1);
BMP_Axis.bmiHeader.biWidth = ctrl_width;
BMP_Axis.bmiHeader.biHeight = ctrl_height;
BMP_Axis.bmiHeader.biBitCount = 24;
BMP_Axis.bmiHeader.biSize = 40;
BMP_Axis.bmiHeader.biPlanes = 1;
BMP_Axis.bmiHeader.biSizeImage = ctrl_width * ctrl_height * 3 + 1024;
BMP_Axis.bmiHeader.biXPelsPerMeter = 2834;
BMP_Axis.bmiHeader.biYPelsPerMeter = 2834;
BMP_Axis.bmiHeader.biCompression = 0;
BMP_Axis.bmiHeader.biClrUsed = 0;
BMP_Axis.bmiHeader.biClrImportant = 0;
for (int i = 0; i < 256; i++)
BMP_Axis.bmiColors[i] = { (unsigned char)i,(unsigned char)i,(unsigned char)i ,0 };
// 图像窗口
x0 = ctrl_width + x0 + margin;
ctrl_width = width - ctrl_width * 2 - margin * 5;
imgwnd_size[0] = ctrl_width -= (ctrl_width % 4);
imgwnd_size[1] = ctrl_height -= (ctrl_height % 4);
hwnd_Image = CreateWindow(L"static", L"实时图像", staticStyle,
x0, y0, ctrl_width, ctrl_height, hparent, NULL, NULL, NULL);
SendMessage(hwnd_Image, WM_SETFONT, (WPARAM)font_normal, 1);
BMP_Image.bmiHeader.biWidth = ctrl_width;
BMP_Image.bmiHeader.biHeight = ctrl_height;
BMP_Image.bmiHeader.biBitCount = 24;
BMP_Image.bmiHeader.biSize = 40;
BMP_Image.bmiHeader.biPlanes = 1;
BMP_Image.bmiHeader.biSizeImage = ctrl_width * ctrl_height * 3 + 1024;
BMP_Image.bmiHeader.biXPelsPerMeter = 2834;
BMP_Image.bmiHeader.biYPelsPerMeter = 2834;
BMP_Image.bmiHeader.biCompression = 0;
BMP_Image.bmiHeader.biClrUsed = 0;
BMP_Image.bmiHeader.biClrImportant = 0;
for (int i = 0; i < 256; i++)
BMP_Image.bmiColors[i] = { (unsigned char)i,(unsigned char)i,(unsigned char)i ,0 };
// 右侧坐标轴标记窗口
ctrl_width = 128;
x0 = width - ctrl_width - margin * 2;
hwnd_Axis_R = CreateWindow(L"static", L"Y坐标轴_R", staticStyle,
x0, y0, ctrl_width, ctrl_height, hparent, NULL, NULL, NULL);
SendMessage(hwnd_Axis_R, WM_SETFONT, (WPARAM)font_normal, 1);
}
// 创建客户界面的函数
bool createUI(HWND hwndmain, WCHAR* szWindowClass, int width, int height,int* analys_size,int* ax_size, int* imgwnd_size)
{
INITCOMMONCONTROLSEX stylesStruct;
stylesStruct.dwSize = sizeof(stylesStruct);
stylesStruct.dwICC = ICC_STANDARD_CLASSES;
InitCommonControlsEx(&stylesStruct);
InitCommonControls(); // 初始化控件库:comctl32.lib comctl32.dll
NONCLIENTMETRICS ncm; // 操作系统使用的字体
ncm.cbSize = sizeof(NONCLIENTMETRICS); // 取出系统的字体作为本应用程序的字体
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0);
// 根据操作系统的字体创建应用程序使用的字体
HFONT hFont_caption; // 标题字体句柄
HFONT hFont_Detail; // 小标题字体句柄
HFONT hFont_normal; // 小标题字体句柄
const int fontSize_caption = 54; // 标题字体的大小
const int detail_fontSize = 32; // 小标题字体的大小
const int normal_fontSize = 24; // 标准字体的大小
createAppFont(&hFont_caption, fontSize_caption, ncm.lfCaptionFont);
createAppFont(&hFont_Detail, detail_fontSize, ncm.lfCaptionFont);
createAppFont(&hFont_normal, normal_fontSize, ncm.lfCaptionFont);
COLORREF CaptionTextColor = RGB(0xFF, 0xFF, 0x00); // 图像窗口文本色
HWND hMain = hwndmain;
int main_width = width, main_height = height, /* 主窗口的宽度、高度 */ margin = 2/* */;
// 状态栏窗口
int statusBarheight = 22, bar_width = main_width / BarNum;
int barWidth[BarNum] = { bar_width,bar_width,bar_width,bar_width,bar_width,0 };
hwndStatusBar = CreateWindowEx(0, L"msctls_statusbar32", L"", WS_VISIBLE | WS_CHILD | WS_BORDER, 0, 0, 0, statusBarheight, hMain, NULL, NULL, NULL);
SendMessage(hwndStatusBar, WM_SETFONT, (WPARAM)hFont_normal, 1);
SetStatus(hMain, hwndStatusBar, BarNum, barWidth);
for (int i = 0; i < BarNum; ++i)
SetStatusBarText(i, status_text[i]);
// Top面板窗口
int height_top = main_height / 12;
HWND hPanel_Top = CreateWindow(szWindowClass, L"top", WS_CHILD | WS_VISIBLE | WS_BORDER,
0, 0, main_width, height_top, hMain, NULL, NULL, NULL);
create_toppannel(hPanel_Top, main_width, width * 2 / 5, height_top, margin, fontSize_caption, hFont_caption, hFont_Detail);
// 右侧视图
int width_right = main_width / 5,
subheight = main_height - statusBarheight - height_top - margin * 3,
x0 = main_width - width_right- margin,
y0 = margin + height_top;
HWND hPanel_right = CreateWindow(szWindowClass, L"right", WS_CHILD | WS_VISIBLE | WS_BORDER,
x0, y0, width_right, subheight, hMain, NULL, NULL, NULL);
createRightPannel(hPanel_right, main_width / 5, subheight,margin, hFont_Detail);
// 左侧视图窗口
int width_left = main_width - width_right - margin * 2;
HWND hPanel_Left = CreateWindow(szWindowClass, L"", WS_CHILDWINDOW | WS_VISIBLE | WS_BORDER,
0, y0, width_left, subheight, hMain, NULL, NULL, NULL);
createLeftPannel(hPanel_Left, width_left, subheight, margin, hFont_normal,analys_size, ax_size,imgwnd_size);
return false;
}
resource.h
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ 生成的包含文件。
// 使用者 VisionGuidance.rc
#define IDS_APP_TITLE 103
#define IDR_MAINFRAME 128
#define IDD_VISIONGUIDANCE_DIALOG 102
#define IDD_ABOUTBOX 103
#define IDM_ABOUT 104
#define IDM_EXIT 105
#define IDI_VISIONGUIDANCE 107
#define IDI_SMALL 108
#define IDC_VISIONGUIDANCE 109
#define IDC_MYICON 2
#ifndef IDC_STATIC
#define IDC_STATIC -1
#endif
// 新对象的下一组默认值
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 130
#define _APS_NEXT_RESOURCE_VALUE 129
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 110
#endif
#endif
framework.h
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容
// Windows 头文件
#include <windows.h>
// C 运行时头文件
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>
targetver.h
#pragma once
// // 包含 SDKDDKVer.h 可定义可用的最高版本的 Windows 平台。
// 如果希望为之前的 Windows 平台构建应用程序,在包含 SDKDDKVer.h 之前请先包含 WinSDKVer.h 并
// 将 _WIN32_WINNT 宏设置为想要支持的平台。
#include <SDKDDKVer.h>
VisionGuidance.h
#pragma once
#include "resource.h"
VisionGuidance.cpp
// VisionGuidance.cpp : 定义应用程序的入口点。
//
#include "pch.h"
#include "framework.h"
#include "VisionGuidance.h"
#include "UI.h"
#define MAX_LOADSTRING 100
// 全局变量:
HINSTANCE hInst; // 当前实例
WCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
WCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK AboutApp(HWND, UINT, WPARAM, LPARAM);
// 此代码模块使用的UI元素
int analysSize[2] = { 0 }; // 分析窗口的尺寸
HWND hwnd_Analys;
BYTE* pAnalysBuff = new BYTE[3840 * 512 * 3];
int axisSize[2] = { 0 }; // 坐标轴窗口的尺寸
HWND hwnd_Axis_L; /* 左侧坐标轴窗口的句柄 */
HWND hwnd_Axis_R; /* 右侧坐标轴窗口的句柄 */
BYTE* pAxisBuff = new BYTE[2160 * 512 * 3];
int imgSize[2] = { 0 }; // 坐标轴窗口的尺寸
HWND hwnd_Image; /* 坐标轴窗口的句柄 */
BYTE* pFrameBuff = new BYTE[3840 * 2160 * 3];
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// TODO: 在此处放置代码。
// 初始化全局字符串
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_VISIONGUIDANCE, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_VISIONGUIDANCE));
MSG msg;
// 主消息循环:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//
// 函数: MyRegisterClass()
//
// 目标: 注册窗口类。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
HBRUSH BackBR = CreateSolidBrush(RGB(0xE0, 0xF0, 0xF0)); // 主窗口的颜色画刷
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_VISIONGUIDANCE));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 3);// BackBR;
wcex.lpszMenuName = NULL /*MAKEINTRESOURCEW(IDC_VISIONGUIDANCE)*/;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
//
// 函数: InitInstance(HINSTANCE, int)
//
// 目标: 保存实例句柄并创建主窗口
//
// 注释:
//
// 在此函数中,我们在全局变量中保存实例句柄并
// 创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // 将实例句柄存储在全局变量中
int mScrWidth = GetSystemMetrics(SM_CXSCREEN); // 主显示器水平分辨率
int mScrHeight = GetSystemMetrics(SM_CYSCREEN); // 主显示器竖直分辨率
HWND hWnd = CreateWindowExW(NULL, szWindowClass, szTitle, WS_POPUPWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, mScrWidth, mScrHeight, nullptr, nullptr, hInstance, nullptr);
if (!hWnd)
{
return FALSE;
}
createUI(hWnd, szWindowClass, mScrWidth, mScrHeight, analysSize, axisSize, imgSize);
for (int i = 0; i < analysSize[1]; ++i)
{
for (int x = 0; x < analysSize[0]; ++x)
{
pAnalysBuff[i * analysSize[0] * 3 + x * 3] = i * 2;
pAnalysBuff[i * analysSize[0] * 3 + x * 3 + 1] = i * 2;
pAnalysBuff[i * analysSize[0] * 3 + x * 3 + 2] = i * 2;
}
}
for (int i = 0; i < axisSize[1]; ++i) {
int value = 0;
for (int x = 0; x < axisSize[0]; ++x) {
if (x < 63)
value += 4;
else
if(x>64)
value -= 4;
pAxisBuff[i * axisSize[0] * 3 + x * 3] = value;
pAxisBuff[i * axisSize[0] * 3 + x * 3 + 1] = value;
pAxisBuff[i * axisSize[0] * 3 + x * 3 + 2] = value;
}
}
for (int i = 0; i < imgSize[1]; ++i) {
for (int x = 0; x < imgSize[0]; ++x) {
pFrameBuff[i * imgSize[0] * 3 + x * 3] = x+i;
pFrameBuff[i * imgSize[0] * 3 + x * 3 + 1] = x / 2;
pFrameBuff[i * imgSize[0] * 3 + x * 3 + 2] = x / 4;
}
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// 函数: OnButtonClicked(HWND, UINT, WPARAM, LPARAM)
//
// 功能: 处理按钮的消息。
//
void OnButtonClicked(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
char msg[256] = { 0 };
int wmId = LOWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDB_EXIT:
if (MessageBox(NULL, TEXT("确认退出吗?"), L"请确认", MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON1) == IDYES)
PostQuitMessage(0);
break;
case IDB_EXIT + 1:
show_imageBuffer(0,hwnd_Analys, pAnalysBuff);
break;
case IDB_EXIT + 2:
show_imageBuffer(1, hwnd_Axis_L, pAxisBuff);
sprintf_s(msg, "IDB_EXIT + 2");
SetStatusBarText(5, msg);
break;
case IDB_EXIT + 3:
show_imageBuffer(2, hwnd_Axis_R, pAxisBuff);
sprintf_s(msg, "IDB_EXIT + 3");
SetStatusBarText(5, msg);
break;
case IDB_EXIT + 4:
show_imageBuffer(3, hwnd_Image, pFrameBuff);
sprintf_s(msg, "IDB_EXIT + 4");
SetStatusBarText(5, msg);
break;
default:
break;
}
}
//
// 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目标: 处理主窗口的消息。
//
// WM_COMMAND - 处理应用程序菜单
// WM_PAINT - 绘制主窗口
// WM_DESTROY - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int m_Ret = 0;
switch (message)
{
case WM_DRAWITEM:
OnDrawItem(hWnd, message, wParam, lParam);
break;
case WM_CTLCOLORBTN:
return (LRESULT)(HBRUSH)GetStockObject(NULL_BRUSH);
break;
case WM_CTLCOLORSTATIC:
return DrawStatic(hWnd, message, wParam, lParam);
break;
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, AboutApp);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
OnButtonClicked(hWnd, message, wParam, lParam);
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_SYSKEYUP:
switch (wParam)
{
case VK_F10: /* F10键属于系统键 */
if (MessageBox(NULL, TEXT("确认退出吗?"), L"请确认", MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON1) == IDYES)
PostQuitMessage(0);
break;
default:
break;
}
break;
case WM_KEYUP: /* 捕获了键盘的功能键操作 */
switch (wParam)
{
case VK_ESCAPE:
if (MessageBox(NULL, TEXT("确认退出吗?"), L"请确认", MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON1) == IDYES)
PostQuitMessage(0);
break;
case VK_F9: /* 关于窗口 */
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, AboutApp);
break;
case VK_F11:/* F11键不属于系统键 */
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, AboutApp);
break;
default:
break;
}
break;
case WM_CHAR:
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// TODO: 在此处添加使用 hdc 的任何绘图代码...
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// “关于”框的消息处理程序。
INT_PTR CALLBACK AboutApp(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}