使用Visual Studio 2022实现透明按钮和标签、POPUP样式窗体的一种工业系统的UI例程

news2024/11/28 14:33:15

例程实现的功能说明

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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/952109.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微软 Turing Bletchley v3视觉语言模型更新:必应搜索图片更精准

据微软新闻稿透露&#xff0c;在推出第三代Turing Bletchley视觉语言模型后&#xff0c;微软计划逐步将其整合到Bing等相关产品中&#xff0c;以提供更出色的图像搜索体验。这款模型最初于2021年11月面世&#xff0c;并在2022年秋季开始邀请用户测试。 凭借用户的反馈和建议&am…

Spring Boot 中 Nacos 配置中心使用实战

官方参考文档 https://nacos.io/zh-cn/docs/quick-start-spring-boot.html 本人实践 1、新建一个spring boot项目 我的spirngboot版本为2.5.6 2、添加一下依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-…

FL studio21.1中文最新版FL萝卜音乐制作软件

FL studio21.1版中文名字叫做水果音乐编曲软件&#xff0c;是一款非常专业的电脑音乐制作软件。全新的21版本在功能上进行了升级&#xff0c;帮助用户来进行编曲、剪辑、录音、混音等多种工作&#xff0c;还可以为用户提供很多音乐创作的灵感&#xff0c;让你制作出各种好听的音…

postgresql-通用表表达式

postgresql-通用表表达式 简介简单 CTE递归 CTE案例1案例2 DML 语句与 CTE 简介 通用表表达式&#xff08;Common Table Expression、CTE&#xff09;是一个临时的查询结果或者临时表&#xff0c;可以 在其他 SELECT、INSERT、UPDATE 以及 DELETE 语句中使用。通用表表达式只在…

关闭jenkins插件提醒信息

jenkins提醒信息和安全警告可以帮助我们了解插件或者jenkins的更新情况&#xff0c;但是有些插件是已经不维护了&#xff0c;提醒却一直存在&#xff0c;看着糟心&#xff0c;就像下面的提示 1、关闭插件提醒 找到如下位置&#xff1a;系统管理-系统配置-管理监控配置 打开管…

SQL注入 - POST注入方法

文章目录 注入流程正常尝试弱口令登录判断是否存在注入&#xff0c;是否会将用户输入拼接到sql语句&#xff0c;并当做代码执行尝试是否需要闭合语句尝试注释掉后面得语句判断字段数判断显错位判断当前数据库名判断当前数据库下的表名判断当前数据库下users表的列名获取usernam…

DHCP中继实验

文章目录 一、实验背景与目的二、实验拓扑三、实验需求四、实验解法1. 配置IP地址2.配置R1为DHCP服务器&#xff0c;能够跨网段为192.168.2.0/24网段自动分配IP地址3. 在PC3上Ping 192.168.1.1&#xff0c;确认可以Ping通 摘要&#xff1a; 本实验旨在通过配置DHCP中继实现跨网…

stm32---用外部中断实现红外接收器

一、红外遥控的原理 红外遥控是一种无线、非接触控制技术&#xff0c;具有抗干扰能力强&#xff0c;信息传 输可靠&#xff0c;功耗低&#xff0c;成本低&#xff0c;易实现等显著优点&#xff0c;被诸多电子设备特别是 家用电器广泛采用&#xff0c;并越来越多的应用到计算机系…

电缆工厂 3D 可视化管控系统 | 智慧工厂

近年来&#xff0c;我国各类器材制造业已经开始向数字化生产转型&#xff0c;使得生产流程变得更加精准高效。通过应用智能设备、物联网和大数据分析等技术&#xff0c;企业可以更好地监控生产线上的运行和质量情况&#xff0c;及时发现和解决问题&#xff0c;从而提高生产效率…

2023-8-30 八数码(BFS)

题目链接&#xff1a;八数码 #include <iostream> #include <algorithm> #include <unordered_map> #include <queue>using namespace std;int bfs(string start) {string end "12345678x";queue<string> q;unordered_map<strin…

[ZenTao]源码阅读:自定义任务类型

1、module/custom/control.php 2、module/custom/model.php

线性代数的学习和整理13: 定义域,值域,到达域 和单射,满射,双射,反函数,逆矩阵

目录 1 函数与 向量/矩阵 2 初等数学的函数 2.1 函数 2.2 函数的定义&#xff1a;定义域 →映射→ 值域 3 高等数学里的函数&#xff1a;定义域和陪域/到达域&#xff08;非值域&#xff09;的映射关系 3.1 函数 3.2 单射&#xff0c;满射&#xff0c;双射等都是针对…

整流二极管 DL4001~DL4007:1000V 1A

国产二极管品牌厂家东沃电子&#xff08;DOWOSEMI&#xff09;推出的整流二极管种类繁多、封装多样、型号齐全&#xff0c;根据正向电流大小来分&#xff0c;有&#xff1a;1A、1.5A、2A、3A、5A、6A、10A等等。关于整流二极管&#xff0c;之前东沃电子科普过很多这方面的知识和…

前端自学总结

文章目录 一、nodejs1.1、npm配置命令别名 二、JavaScript2.1、javascript注释 一、nodejs 1.1、npm配置命令别名 我们可以使用“node index.js”的方式运行代码 也可以利用npm配置别名的方式运行代码 在package.json中配置别名&#xff0c;利用“npm run 别名”也可以运行 st…

5000字详解OpenAI超级对齐四年计划:定义、挑战与方法

导读 超级智能是一把双刃剑&#xff0c;有助于解决许多重要问题&#xff0c;同时也可能削弱人类的权力并威胁我们的安全。为了治理这些风险&#xff0c;急需建立新的治理机构并解决AI模型的对齐问题。OpenAI于今年7月首次提出超级对齐的概念&#xff0c;并宣布投入20%的计算资源…

【CSS】简记CSS效果:通过transition(动画过渡属性)实现侧边栏目滑入滑出

需求 在资金明细的页面中&#xff0c;点击按钮时筛选区域从左侧滑出&#xff0c;完成筛选点击确认后调用接口完成数据查询&#xff0c;筛选区域滑入左侧&#xff1b; 基于微信小程序页面实现 wxml代码 <view><!-- 操作按钮 --><button type"primary&qu…

Matlab图像处理-图像旋转

基本概念 图像的旋转变换属于图像的位置变换&#xff0c;通常是以图像的中心为原点&#xff0c;将图像上的所有像素都旋转一个相同的角度。旋转后&#xff0c;图像的大小一般会改变。图像的旋转变换是指以图像的中心为原点&#xff0c;将图像上的所有像素都旋转同一个角度的变…

十、桥接模式

一、什么是桥接模式 桥接&#xff08;Bridge&#xff09;模式的定义如下&#xff1a;将抽象与实现分离&#xff0c;使它们可以独立变化。它是用组合关系代替继承关系来实现&#xff0c;从而降低了抽象和实现这两个可变维度的耦合度。 桥接&#xff08;Bridge&#xff09;模式包…

浅析token

上一章节我们学习了cookie和session机制&#xff0c;但是他们都有一些缺点&#xff0c;所有这次我们来了解一个机制---token。 一、cookie和session的缺点 cookie信息存储在客户端浏览器上&#xff0c;安全性较低&#xff0c;所以浏览器加入了一些限制确保cookie不会被恶意使用…

对称二叉树判断

目录 题目题目要求示例 解答方法一、实现思路时间复杂度和空间复杂度代码 方法二、实现思路时间复杂度和空间复杂度代码 题目 对称二叉树判断 题目要求 题目链接 示例 解答 方法一、 递归法 实现思路 使用到了判断两棵二叉树是否相等的方法&#xff0c;只不过对称二叉树…