WinAPI: CreatePen - 建立画笔

本文深入探讨了编程领域中,为何大部分程序员难以晋升为架构师的原因,从技术能力、思维模式、沟通协作等多个维度解析这一现象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//声明:
CreatePen(
  Style, Width: Integer; {样式与笔宽}
  Color: COLORREF        {颜色}
): HPEN;                 {返回笔句柄}

//Style 参数可选值:
PS_SOLID       = 0; {实线}
PS_DASH        = 1; {段线; 要求笔宽<=1}
PS_DOT         = 2; {点线; 要求笔宽<=1}
PS_DASHDOT     = 3; {线、点; 要求笔宽<=1}
PS_DASHDOTDOT  = 4; {线、点、点; 要求笔宽<=1}
PS_NULL        = 5; {不可见}
PS_INSIDEFRAME = 6; {实线; 但笔宽是向里扩展}

 
 
 
 
 

 

 

  

//举例:
procedure TForm1.FormPaint(Sender: TObject);
var
  PenStyle: Integer; {Pen 样式}
  PenHandle: HPEN;   {Pen 句柄}
begin
  PenStyle := RadioGroup1.ItemIndex;

  PenHandle := CreatePen(PenStyle, 1, clRed);
  Canvas.Pen.Handle := PenHandle;
  Rectangle(Canvas.Handle, 20, 20, 96,160);
  DeleteObject(PenHandle);
end;

procedure TForm1.RadioGroup1Click(Sender: TObject);
begin
  Self.Refresh;
end;

 
 
 
 
 

 

 

  

//效果图:
26154056_QPRn.png 26154056_YWrk.png 26154056_d2Ns.png 26154056_QYrQ.png 26154056_vyh9.png 26154056_nJC0.png 26154056_2b9T.png
//测试 PS_SOLID 与 PS_INSIDEFRAME 的区别
procedure TForm1.FormPaint(Sender: TObject);
var
  PenHandle: HPEN;
begin
  PenHandle := CreatePen(PS_SOLID, 20, clRed);
  Canvas.Pen.Handle := PenHandle;
  Rectangle(Canvas.Handle, 20, 20, 96,132);

  PenHandle := CreatePen(PS_INSIDEFRAME, 20, clRed);
  Canvas.Pen.Handle := PenHandle;
  Rectangle(Canvas.Handle, 120, 20, 196,132);

  PenHandle := CreatePen(PS_SOLID, 1, clRed);
  Canvas.Pen.Handle := PenHandle;
  Rectangle(Canvas.Handle, 220, 20, 296,132);

  DeleteObject(PenHandle);
end;

 
 
 
 
 

 

 

  

//效果图:
26154056_Fu2t.png

转载于:https://my.oschina.net/hermer/blog/321018

#include <Windows.h> #include <commctrl.h> #include "aip_commom.h" // 全局变量 U2 u2_g_position_ax; U2 u2_g_position_ay; U2 u2_g_position_bx; U2 u2_g_position_by; U1 pointsSet = FALSE; // 函数声明 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); /*===================================================================================================================================*/ /* WinMain : Windows应用程序入口点,负责窗口注册、创建和消息循环 */ /* --------------------------------------------------------------------------------------------------------------------------------- */ /* Arguments: hInstance hInstance : 当前程序实例句柄 */ /* hInstance hPrevInstance : 前一个实例句柄(已废弃) */ /* LPSTR lpCmdLine : 命令行参数 */ /* U4 nCmdShow : 窗口显示方式 */ /* Return: U4 : 消息循环退出码 */ /*===================================================================================================================================*/ U4 WINAPI WinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ U4 nCmdShow)//通过ShowWindow(hwn, nCmdShow)设置窗口的显示方式。 { const wchar_t Creat_WinID[] = L"FirstQuadrantWindowClass";////声明一个常量宽字符串作为窗口类的唯一标识符,用于后续窗口创建时引用。L将字符设计为wchar_t宽字符类型 // 注册窗口类 WNDCLASS cw = { ZERO }; cw.lpszClassName = Creat_WinID;//为窗口类提供一个字符串标识符。后续创建窗口时需通过此名称引用已注册的窗口类。 cw.lpfnWndProc = WndProc;//指定处理窗口消息的回调函数。操作系统将窗口事件(如鼠标点击、键盘输入、窗口绘制等)发送到该函数。 cw.hInstance = hInstance;//标识当前应用程序实例。在Windows中,每个运行的程序都有一个唯一的实例句柄,用于资源管理和进程区分。 cw.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); //定义窗口客户区的背景颜色。当窗口需要重绘背景时(如收到WM_ERASEBKGND消息),系统使用该画刷填充背景。 RegisterClass(&cw);//向操作系统注册此窗口类,使其可用于后续的窗口创建。这是创建任何Windows窗口的必要前置步骤 // 创建主窗口 //dwExStyle:窗口的扩展样式 //lpClassName:窗口类名标识符 //lpWindowName:窗口显示栏文本 //dwStyle:窗口主样式组合 //x/y:初始屏幕坐标 //nWidth/nHeight:窗口尺寸 //hWndParent:父窗口句柄 //hMenu:菜单句柄 //hInstance:应用程序实例句柄 //lpParam:传递给窗口的额外数据 HWND hwn = CreateWindowEx(ZERO,Creat_WinID,L"C语言作业第一题",WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME,CW_USEDEFAULT, CW_USEDEFAULT,WINDOW_WIDTH, WINDOW_HEIGHT,NULL, NULL, hInstance, NULL); // 创建输入控件 CreateWindow(L"STATIC", L"AX:", WS_CHILD | WS_VISIBLE,AX_LABEL_X, CONTROL_TOP, LABEL_XWIDTH, CONTROL_HEIGHT,hwn, NULL, hInstance, NULL); CreateWindow(L"EDIT", L"100", WS_CHILD | WS_VISIBLE | WS_BORDER,AX_EDIT_X, CONTROL_TOP, EDIT_WIDTH, CONTROL_HEIGHT,hwn, (HMENU)ID_AX, hInstance, NULL); CreateWindow(L"STATIC", L"AY:", WS_CHILD | WS_VISIBLE,AY_LABEL_X, CONTROL_TOP, LABEL_YWIDTH, CONTROL_HEIGHT,hwn, NULL, hInstance, NULL); CreateWindow(L"EDIT", L"100", WS_CHILD | WS_VISIBLE | WS_BORDER,AY_EDIT_X, CONTROL_TOP, EDIT_WIDTH, CONTROL_HEIGHT,hwn, (HMENU)ID_AY, hInstance, NULL); CreateWindow(L"STATIC", L"BX:", WS_CHILD | WS_VISIBLE,BX_LABEL_X, CONTROL_TOP, LABEL_XWIDTH, CONTROL_HEIGHT,hwn, NULL, hInstance, NULL); CreateWindow(L"EDIT", L"400", WS_CHILD | WS_VISIBLE | WS_BORDER,BX_EDIT_X, CONTROL_TOP, EDIT_WIDTH, CONTROL_HEIGHT,hwn, (HMENU)ID_BX, hInstance, NULL); CreateWindow(L"STATIC", L"BY:", WS_CHILD | WS_VISIBLE,BY_LABEL_X, CONTROL_TOP, LABEL_YWIDTH, CONTROL_HEIGHT,hwn, NULL, hInstance, NULL); CreateWindow(L"EDIT", L"400", WS_CHILD | WS_VISIBLE | WS_BORDER,BY_EDIT_X, CONTROL_TOP, EDIT_WIDTH, CONTROL_HEIGHT,hwn, (HMENU)ID_BY, hInstance, NULL); // 创建绘制按钮 CreateWindow(L"BUTTON", L"绘制", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,BUTTON_X, CONTROL_TOP, BUTTON_WIDTH, BUTTON_HEIGHT,hwn, (HMENU)ID_BUTTON_DRAW, hInstance, NULL); // 显示窗口 ShowWindow(hwn, nCmdShow); UpdateWindow(hwn); // 消息循环 MSG msg; while (GetMessage(&msg, NULL, ZERO, ZERO)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (U4)msg.wParam; } /*===================================================================================================================================*/ /* GetEditUShort : 从编辑框控件获取并验证输入的坐标值 */ /* --------------------------------------------------------------------------------------------------------------------------------- */ /* Arguments: hwnd hwnd : 父窗口句柄 */ /* U4 ctrlID : 编辑框控件ID */ /* Return: U2 : 验证后的坐标值(范围0-500) */ /*===================================================================================================================================*/ U2 u2_g_GetValue(HWND hwn, U4 ctrlID) { wchar_t text[TEXT_BUFFER_SIZE];//声明一个宽字符数组作为缓冲区。 GetDlgItemText(hwn, ctrlID, text, TEXT_BUFFER_SIZE);//使用GetDlgItemText获取控件中的文本。 U4 u4_t_GetMessage_value = _wtoi(text);//使用_wtoi将文本转换为整数(U4,即32位无符号整数)。 if (u4_t_GetMessage_value < MIN_COORD) { u4_t_GetMessage_value = MIN_COORD; } else { } if (u4_t_GetMessage_value > MAX_COORD) { u4_t_GetMessage_value = MAX_COORD; } else { } return (U2)u4_t_GetMessage_value; } /*===================================================================================================================================*/ /* WndProc : 主窗口消息处理函数,处理窗口命令、绘制和销毁事件 */ /* --------------------------------------------------------------------------------------------------------------------------------- */ /* Arguments: hwnd hwnd : 窗口句柄 */ /* UINT msg : 消息类型 */ /* WPARAM wParam: 消息参数 */ /* LPARAM lParam: 消息参数 */ /* Return: LRESULT : 消息处理结果 */ /*===================================================================================================================================*/ LRESULT CALLBACK WndProc(HWND hwn, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_COMMAND: if (LOWORD(wParam) == ID_BUTTON_DRAW) { u2_g_position_ax = u2_g_GetValue(hwn, ID_AX); u2_g_position_ay = u2_g_GetValue(hwn, ID_AY); u2_g_position_bx = u2_g_GetValue(hwn, ID_BX); u2_g_position_by = u2_g_GetValue(hwn, ID_BY); pointsSet = TRUE; InvalidateRect(hwn, NULL, TRUE); } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hwn, &ps); // 设置坐标系参数 U4 u4_t_Draw_originX; U4 u4_t_Draw_originY; U4 u4_t_Draw_axisLength; u4_t_Draw_originX = ORIGIN_X; u4_t_Draw_originY = ORIGIN_Y; u4_t_Draw_axisLength = AXIS_LENGTH; // 创建白色画笔用于坐标轴 HPEN WhitePen = CreatePen(PS_SOLID, StrokeWidth, COLOR_WHITE); HPEN hOldPen = (HPEN)SelectObject(hdc, WhitePen); // 绘制X轴 MoveToEx(hdc, u4_t_Draw_originX, u4_t_Draw_originY, NULL); LineTo(hdc, u4_t_Draw_originX + u4_t_Draw_axisLength, u4_t_Draw_originY); // 绘制Y轴 MoveToEx(hdc, u4_t_Draw_originX, u4_t_Draw_originY, NULL); LineTo(hdc, u4_t_Draw_originX, u4_t_Draw_originY - u4_t_Draw_axisLength); // 绘制X轴箭头 MoveToEx(hdc, u4_t_Draw_originX + u4_t_Draw_axisLength, u4_t_Draw_originY, NULL); LineTo(hdc, u4_t_Draw_originX + u4_t_Draw_axisLength - ARROW_SIZE, u4_t_Draw_originY - ARROW_OFFSET); MoveToEx(hdc, u4_t_Draw_originX + u4_t_Draw_axisLength, u4_t_Draw_originY, NULL); LineTo(hdc, u4_t_Draw_originX + u4_t_Draw_axisLength - ARROW_SIZE, u4_t_Draw_originY + ARROW_OFFSET); // 绘制Y轴箭头 MoveToEx(hdc, u4_t_Draw_originX, u4_t_Draw_originY - u4_t_Draw_axisLength, NULL); LineTo(hdc, u4_t_Draw_originX - ARROW_OFFSET, u4_t_Draw_originY - u4_t_Draw_axisLength + ARROW_SIZE); MoveToEx(hdc, u4_t_Draw_originX, u4_t_Draw_originY - u4_t_Draw_axisLength, NULL); LineTo(hdc, u4_t_Draw_originX + ARROW_OFFSET, u4_t_Draw_originY - u4_t_Draw_axisLength + ARROW_SIZE); // 标注坐标轴 SetTextColor(hdc, COLOR_WHITE); SetBkColor(hdc, COLOR_BLACK); TextOut(hdc, u4_t_Draw_originX + u4_t_Draw_axisLength - AXIS_LABEL_OFFSET, u4_t_Draw_originY + AXIS_LABEL_OFFSET, L"X", ONE); TextOut(hdc, u4_t_Draw_originX - AXIS_LABEL_OFFSET, u4_t_Draw_originY - u4_t_Draw_axisLength + AXIS_LABEL_Y_OFFSET, L"Y", ONE); TextOut(hdc, u4_t_Draw_originX - ORIGIN_LABEL_OFFSET, u4_t_Draw_originY + ORIGIN_LABEL_OFFSET , L"O", ONE); // 如果设置了点,绘制点和连线 if (pointsSet) { // 计算实际绘制位置 U4 u4_t_Draw_Ax = u4_t_Draw_originX + u2_g_position_ax; U4 u4_t_Draw_Ay = u4_t_Draw_originY - u2_g_position_ay; U4 u4_t_Draw_Bx = u4_t_Draw_originX + u2_g_position_bx; U4 u4_t_Draw_By = u4_t_Draw_originY - u2_g_position_by; // 绘制点 Drawpixel(hdc, u4_t_Draw_originX, u4_t_Draw_originY, u2_g_position_ax, u2_g_position_ay); Drawpixel(hdc, u4_t_Draw_originX, u4_t_Draw_originY, u2_g_position_bx, u2_g_position_by); // 标记点 SetTextColor(hdc, COLOR_LIGHT_RED); SetBkMode(hdc, TRANSPARENT); TextOut(hdc, u4_t_Draw_Ax + POINT_LABEL_OFFSET, u4_t_Draw_Ay - POINT_LABEL_OFFSET, L"A", ONE); SetTextColor(hdc, COLOR_LIGHT_BLUE); TextOut(hdc, u4_t_Draw_Bx + POINT_LABEL_OFFSET, u4_t_Draw_By - POINT_LABEL_OFFSET, L"B", ONE); // 创建红色画笔用于连接线 HPEN hRedPen = CreatePen(PS_SOLID, StrokeWidth, COLOR_RED); SelectObject(hdc, hRedPen); // 绘制直线 MoveToEx(hdc, u4_t_Draw_Ax, u4_t_Draw_Ay, NULL); LineTo(hdc, u4_t_Draw_Bx, u4_t_Draw_By); } else { } } } return DefWindowProc(hwn, msg, wParam, lParam); } 该代码在绘制一次后是如何覆盖本次绘制进行下一次绘制的?用到了那些函数?
最新发布
07-26
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值