我又又又更新了!纯手工编写C++画图,有注释!!!!!

再再次感谢Ttcofee提的问题

        本次更新内容:

                   缩小到托盘,获取系统时间

提前申明:如果运行不了,请到主页查看RedpandaDevc++下载,若还是不行就卸了重装。

#include <windows.h>
#include <gdiplus.h>
#include <string>
#include <iostream>
// 控件和消息定义
#define IDC_BTN_GETTIME  1007
#define IDC_STATIC_TIME  1008
#define IDC_EDIT_PWD   1001
#define IDC_BTN_TOGGLE 1002
#define IDC_EDIT1        1003
#define IDC_BUTTON_SUBMIT 1004
#define IDC_BTN_TRAY    1005
#define WM_TRAY_ICON    1006
using namespace std;
HWND g_hwnd;
NOTIFYICONDATA g_nid = {0};
bool g_isInTray = false;
HWND hEdit;
HWND hButton,hButton2;
POINT g_startPos, g_endPos;
RECT g_originalRect;
LONG_PTR g_originalStyle;
bool g_isFullscreen = false;
HBITMAP g_hMemBitmap = NULL;
HDC g_hMemDC = NULL;
int g_width = 0, g_height = 0;
bool g_isPasswordMode = true; // 初始为密码模式

void InitTrayIcon(HWND hwnd) {
    g_nid.cbSize = sizeof(NOTIFYICONDATA);
    g_nid.hWnd = hwnd;
    g_nid.uID = 1;
    g_nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
    g_nid.uCallbackMessage = WM_TRAY_ICON;
    g_nid.hIcon = LoadIcon(NULL, IDI_APPLICATION);
}

// 切换托盘状态
void ToggleTrayMode(HWND hwnd) {
    if (!g_isInTray) {
        // 最小化到托盘
        ShowWindow(hwnd, SW_HIDE);
        Shell_NotifyIcon(NIM_ADD, &g_nid);
    } else {
        // 恢复窗口
        ShowWindow(hwnd, SW_SHOW);
        Shell_NotifyIcon(NIM_DELETE, &g_nid);
    }
    g_isInTray = !g_isInTray;
}

// 初始化双缓冲
void InitDoubleBuffer(HWND hwnd) {
	RECT rc;
	GetClientRect(hwnd, &rc);
	g_width = rc.right - rc.left;
	g_height = rc.bottom - rc.top;
	HDC hdc = GetDC(hwnd);
	g_hMemDC = CreateCompatibleDC(hdc);
	g_hMemBitmap = CreateCompatibleBitmap(hdc, g_width, g_height);
	SelectObject(g_hMemDC, g_hMemBitmap);
	ReleaseDC(hwnd, hdc);
	// 初始清屏(可选)
	FillRect(g_hMemDC, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH));
}
// 切换全屏函数
void ToggleFullscreen(HWND hwnd) {
	if (!g_isFullscreen) {
		// 进入全屏
		GetWindowRect(hwnd, &g_originalRect);
		g_originalStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
		int screenWidth = GetSystemMetrics(SM_CXSCREEN);
		int screenHeight = GetSystemMetrics(SM_CYSCREEN);

		SetWindowLongPtr(hwnd, GWL_STYLE, WS_POPUP);
		SetWindowPos(hwnd, HWND_TOP,
		             0, 0, screenWidth, screenHeight,
		             SWP_FRAMECHANGED | SWP_SHOWWINDOW
		            );
	} else {
		// 退出全屏
		SetWindowLongPtr(hwnd, GWL_STYLE, g_originalStyle);
		SetWindowPos(hwnd, NULL,
		             g_originalRect.left,
		             g_originalRect.top,
		             g_originalRect.right - g_originalRect.left,
		             g_originalRect.bottom - g_originalRect.top,
		             SWP_FRAMECHANGED | SWP_NOZORDER
		            );
	}
	g_isFullscreen = !g_isFullscreen;
}

// 切换密码显示模式
void TogglePasswordMode(HWND hwnd) {
    // 保存当前文本
    wchar_t szText[256] = {0};
    GetWindowTextW(hEdit, szText, 256);

    // 获取当前窗口位置
    RECT rc;
    GetWindowRect(hEdit, &rc);
    MapWindowPoints(HWND_DESKTOP, GetParent(hEdit), (LPPOINT)&rc, 2);

    // 销毁旧编辑框
    DestroyWindow(hEdit);

    // 创建新编辑框(切换样式)
    DWORD style = WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL;
    if (g_isPasswordMode) {
        style |= ES_PASSWORD;
    }

    hEdit = CreateWindowW(
        L"EDIT", szText,
        style,
        rc.left, rc.top,
        rc.right - rc.left,
        rc.bottom - rc.top,
        hwnd, (HMENU)IDC_EDIT_PWD,
        NULL,
        NULL
    );

    // 更新模式状态
    g_isPasswordMode = !g_isPasswordMode;

    // 更新按钮文本
    SetWindowTextW(GetDlgItem(hwnd, IDC_BTN_TOGGLE),
        g_isPasswordMode ? L"隐藏密码" : L"显示明文");
}

// 窗口过程函数
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    static HWND hStaticTime; // 静态文本控件句柄
	switch (msg) {
		case WM_SIZE:
			// 窗口大小变化时重置缓冲
			if (g_hMemDC) {
				DeleteDC(g_hMemDC);
				DeleteObject(g_hMemBitmap);
			}
			InitDoubleBuffer(hwnd);
			break;
		case WM_KEYDOWN:
			if (wParam == VK_BACK) { // 按Backspace切换全屏
				ToggleFullscreen(hwnd);
			} else if (wParam == VK_CONTROL) {
				DestroyWindow(hwnd);
				HWND hwnwd;
				hwnwd = FindWindow("ConsoleWindowClass", NULL);
				if (hwnwd) {
					ShowOwnedPopups(hwnwd, SW_SHOW);
					ShowWindow(hwnwd, SW_SHOW);
				}
			}
			return 0;
		case WM_PAINT: { // 窗口需要绘制时触发
			PAINTSTRUCT ps;
			HDC hdc = BeginPaint(hwnd, &ps);  // 获取设备上下文
			// 设置背景模式为透明
			BitBlt(hdc, 0, 0, g_width, g_height, g_hMemDC, 0, 0, SRCCOPY);
			SetBkMode(hdc, TRANSPARENT);
			HPEN hDashPen = CreatePen(PS_DASH, 1, RGB(256, 256, 256));
			SelectObject(hdc, hDashPen);
			MoveToEx(hdc, g_startPos.x, g_startPos.y, NULL);
			LineTo(hdc, g_endPos.x, g_endPos.y);
			return 0;
		}
		case WM_CLOSE:
            // 清理托盘图标
            if (g_isInTray) Shell_NotifyIcon(NIM_DELETE, &g_nid);
            DestroyWindow(hwnd);	
			break;
		case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
			break;
		// 处理鼠标消息
		case WM_LBUTTONDOWN:
			g_startPos.x = LOWORD(lParam);
			g_startPos.y = HIWORD(lParam);
			return 0;

		case WM_MOUSEMOVE:
			if (wParam & MK_LBUTTON) {
				g_endPos.x = LOWORD(lParam);
				g_endPos.y = HIWORD(lParam);
				InvalidateRect(hwnd, NULL, TRUE);
			}
			return 0;
		case WM_ERASEBKGND:
			return 1; // 禁用背景擦除
        case WM_CREATE: {
            // 创建"获取时间"按钮
            CreateWindowW(L"BUTTON", L"获取时间",
                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                20, 370, 100, 30,
                hwnd, (HMENU)IDC_BTN_GETTIME, NULL, NULL);

            // 创建显示时间的静态文本
            hStaticTime = CreateWindowW(L"STATIC", L"时间未获取",
                WS_CHILD | WS_VISIBLE | SS_LEFT,
                20,420, 200, 20,
                hwnd, (HMENU)IDC_STATIC_TIME, NULL, NULL);
            // 创建按钮
            CreateWindowW(L"BUTTON", L"最小化到托盘",
                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                400, 50, 150, 30, hwnd, 
                (HMENU)IDC_BTN_TRAY, NULL, NULL);
            
            // 初始化托盘
            InitTrayIcon(hwnd);
            // 创建按钮
            hButton = CreateWindow(
                "BUTTON",                     // 窗口类(按钮)
                "点击我关闭",                     // 按钮文本
                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, // 样式
                50, 50,                       // 位置 (x, y)
                100, 30,                       // 大小 (宽度, 高度)
                hwnd,                         // 父窗口句柄
                (HMENU)1,                     // 控件ID
                ((LPCREATESTRUCT)lParam)->hInstance, // 实例句柄
                NULL                          // 附加数据
            ); 
            hButton2 = CreateWindow(
                "BUTTON",                     // 窗口类(按钮)
                "点击我切换全屏",                     // 按钮文本
                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, // 样式
                850, 50,                       // 位置 (x, y)
                100, 30,                       // 大小 (宽度, 高度)
                hwnd,                         // 父窗口句柄
                (HMENU)2,                     // 控件ID
                ((LPCREATESTRUCT)lParam)->hInstance, // 实例句柄
                NULL                          // 附加数据
            ); 	

            // 创建切换按钮
            CreateWindowW(
                L"BUTTON", L"隐藏密码",
                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                100, 300, 80, 30,
                hwnd, (HMENU)IDC_BTN_TOGGLE,
                NULL, NULL
            );	
            hEdit = CreateWindowW(L"EDIT", L"", 
                WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,
                20, 250, 200, 25, hwnd,  (HMENU)IDC_EDIT1, NULL, NULL);
            
            CreateWindowW(L"BUTTON", L"示例输入",
                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                20, 300, 80, 30, hwnd, (HMENU)IDC_BUTTON_SUBMIT, NULL, NULL);	         
            return 0;
        }
        case WM_TRAY_ICON:
            if (lParam == WM_LBUTTONDBLCLK) {
                ToggleTrayMode(hwnd);
            }
            return 0;
        // 禁用系统最小化操作
        case WM_SYSCOMMAND:
            if (wParam == SC_MINIMIZE) {
                ToggleTrayMode(hwnd);
                return 0;
            }
            break;
        case WM_COMMAND: {
            if (LOWORD(wParam) == IDC_BTN_TRAY) {
                ToggleTrayMode(hwnd);
            }
            if (LOWORD(wParam) == IDC_BUTTON_SUBMIT) {
                wchar_t buffer[256];
                GetWindowTextW(hEdit, buffer, 256);
                
                if (wcslen(buffer) == 0) {
                    MessageBoxW(hwnd, L"输入不能为空!", L"错误", MB_ICONERROR);
                } else {
                    MessageBoxW(hwnd, buffer, L"输入内容", MB_OK);
                }
            }
            if (LOWORD(wParam) == IDC_BTN_TOGGLE) {
                TogglePasswordMode(hwnd);
            }
            int ButtonID=LOWORD(wParam);
            switch(ButtonID){
				case 1:
					DestroyWindow(hwnd);
					HWND hwnwd;
					hwnwd = FindWindow("ConsoleWindowClass", NULL);
					if (hwnwd) {
						ShowOwnedPopups(hwnwd, SW_SHOW);
						ShowWindow(hwnwd, SW_SHOW);
					}
					break;
				case 2:
					ToggleFullscreen(hwnd);
					break;			
			}
            if (LOWORD(wParam) == IDC_BTN_GETTIME) {
                // 获取本地时间
                SYSTEMTIME st;
                GetLocalTime(&st);

                // 格式化时间字符串
                wchar_t timeStr[64];
                _snwprintf(timeStr, 64,
                    L"%04d-%02d-%02d %02d:%02d:%02d",
                    st.wYear, st.wMonth, st.wDay,
                    st.wHour, st.wMinute, st.wSecond);

                // 更新静态文本
                SetWindowTextW(hStaticTime, timeStr);
                // 可选:弹出消息框显示
                MessageBoxW(hwnd, timeStr, L"系统时间", MB_OK);
            }
            return 0;
        }     
		default:
			return DefWindowProc(hwnd, msg, wParam, lParam);
	}
	return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR pCmdLine, int nCmdShow) {
	HWND hwnwd;
	hwnwd = FindWindow("ConsoleWindowClass", NULL);
	if (hwnwd) {
		ShowOwnedPopups(hwnwd, SW_HIDE);
		ShowWindow(hwnwd, SW_HIDE);
	}
	const char* CLASS_NAME = "CustomWindowClass";

	WNDCLASS wc = {};
	wc.lpfnWndProc = WndProc;
	wc.hInstance = hInstance;
	wc.lpszClassName = TEXT(CLASS_NAME);
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);

	if (!RegisterClass(&wc)) return 0;

	// 创建窗口
	HWND hwnd = CreateWindowEx(
	                0,                              // 扩展样式
	                TEXT(CLASS_NAME),                     // 窗口类
	                " 绘画",                   // 窗口标题
	                WS_OVERLAPPEDWINDOW | WS_VISIBLE, // 窗口样式
	                CW_USEDEFAULT, CW_USEDEFAULT,   // 位置
	                1000, 1000,                       // 大小
	                NULL,                           // 父窗口
	                NULL,                           // 菜单
	                hInstance,                      // 实例句柄
	                NULL                            // 附加数据
	            );

	if (!hwnd) return 0;

	// 消息循环
	MSG msg = {};
	while (GetMessage(&msg, NULL, 0, 0)) {
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return 0;
}

制作不易

点亮再看

还有彩蛋

#include <windows.h>

// 全局变量存储按钮句柄
HWND hButton,hhh2;
// 窗口过程函数
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch (msg) {
        case WM_CREATE: {
            // 创建按钮
            hButton = CreateWindow(
                "BUTTON",                     // 窗口类(按钮)
                "点击我",                     // 按钮文本
                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, // 样式
                50, 50,                       // 位置 (x, y)
                100, 30,                       // 大小 (宽度, 高度)
                hwnd,                         // 父窗口句柄
                (HMENU)1,                     // 控件ID
                ((LPCREATESTRUCT)lParam)->hInstance, // 实例句柄
                NULL                          // 附加数据
            );
            // 创建按钮
            hhh2 = CreateWindow(
                "BUTTON",                     // 窗口类(按钮)
                "点击我",                     // 按钮文本
                WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, // 样式
                150, 50,                       // 位置 (x, y)
                100, 30,                       // 大小 (宽度, 高度)
                hwnd,                         // 父窗口句柄
                (HMENU)1,                     // 控件ID
                ((LPCREATESTRUCT)lParam)->hInstance, // 实例句柄
                NULL                          // 附加数据
            );           
            return 0;
        }
        case WM_COMMAND: {
            // 处理按钮点击
            if (LOWORD(wParam) == 1) {  // 控件ID为1
                MessageBox(hwnd, "按钮被点击了!", "提示", MB_OK);
        		Sleep(1000);
            }
            return 0;
        }
        case WM_CLOSE:
            DestroyWindow(hwnd);
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}

// WinMain 函数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    const char CLASS_NAME[] = "MyWindowClass";

    WNDCLASS wc = {};
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = CLASS_NAME;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);

    if (!RegisterClass(&wc)) return 0;

    HWND hwnd = CreateWindowEx(
        0,
        CLASS_NAME,
        "按钮示例",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        400, 300,
        NULL, NULL, hInstance, NULL
    );

    if (!hwnd) return 0;

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}
#include <windows.h>
#include <vector>
using namespace std;

// 全局变量
std::vector<POINT> g_drawingPoints;  // 记录所有绘制点
HDC g_hMemDC = NULL;                // 内存设备上下文
HBITMAP g_hMemBmp = NULL;           // 内存位图
int g_winWidth = 0, g_winHeight = 0; // 窗口尺寸

// 初始化/重置双缓冲
void InitDoubleBuffer(HWND hwnd) {
    // 释放旧资源
    if (g_hMemDC) DeleteDC(g_hMemDC);
    if (g_hMemBmp) DeleteObject(g_hMemBmp);

    // 获取窗口尺寸
    RECT rc;
    GetClientRect(hwnd, &rc);
    g_winWidth = rc.right;
    g_winHeight = rc.bottom;

    // 创建内存DC和位图
    HDC hdc = GetDC(hwnd);
    g_hMemDC = CreateCompatibleDC(hdc);
    g_hMemBmp = CreateCompatibleBitmap(hdc, g_winWidth, g_winHeight);
    SelectObject(g_hMemDC, g_hMemBmp);
    
    // 初始清空为白色背景
    FillRect(g_hMemDC, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH));
    ReleaseDC(hwnd, hdc);
}

// 窗口过程
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    static POINT prevPt = { -1, -1 }; // 记录前一个点

    switch (msg) {
        case WM_CREATE:
            InitDoubleBuffer(hwnd);
            return 0;

        case WM_SIZE:
            InitDoubleBuffer(hwnd); // 窗口大小变化时重置缓冲
            return 0;

        case WM_LBUTTONDOWN:
            prevPt.x = LOWORD(lParam);
            prevPt.y = HIWORD(lParam);
            g_drawingPoints.push_back(prevPt); // 记录起点
            return 0;

        case WM_MOUSEMOVE:
            if (wParam & MK_LBUTTON) {
                POINT currPt = { LOWORD(lParam), HIWORD(lParam) };
                
                // 在内存DC绘制线段
                HPEN hPen = CreatePen(PS_SOLID, 2, RGB(0,0,255));
                SelectObject(g_hMemDC, hPen);
                
                if (prevPt.x != -1) {
                    MoveToEx(g_hMemDC, prevPt.x, prevPt.y, NULL);
                    LineTo(g_hMemDC, currPt.x, currPt.y);
                }
                
                DeleteObject(hPen);
                
                // 更新记录点
                prevPt = currPt;
                g_drawingPoints.push_back(currPt);

                // 标记需要重绘的区域
                RECT updateRect = { 
                    min(prevPt.x, currPt.x) - 2, 
                    min(prevPt.y, currPt.y) - 2,
                    max(prevPt.x, currPt.x) + 2,
                    max(prevPt.y, currPt.y) + 2
                };
                InvalidateRect(hwnd, &updateRect, FALSE);
            }
            return 0;

        case WM_PAINT: {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);
            
            // 将内存内容复制到屏幕
            BitBlt(hdc, 0, 0, g_winWidth, g_winHeight, g_hMemDC, 0, 0, SRCCOPY);
            
            EndPaint(hwnd, &ps);
            return 0;
        }

        case WM_ERASEBKGND:
            return 1; // 阻止系统擦除背景

        case WM_CLOSE:
            DestroyWindow(hwnd);
            return 0;

        case WM_DESTROY:
            // 清理资源
            if (g_hMemDC) DeleteDC(g_hMemDC);
            if (g_hMemBmp) DeleteObject(g_hMemBmp);
            PostQuitMessage(0);
            return 0;

        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
}

// WinMain
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int nCmdShow) {
    const char* CLASS_NAME = "DrawingWindow";

    WNDCLASS wc = {};
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = CLASS_NAME;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    RegisterClass(&wc);

    HWND hwnd = CreateWindowEx(0, CLASS_NAME, "绘图保留示例",
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
        800, 600, NULL, NULL, hInstance, NULL);

    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值