简介本资源是一份面向C初学者与Windows桌面开发入门者的MFC图形绘制实践项目聚焦于使用MFC框架在视图中动态绘制直线、矩形和椭圆三大基础图形解决GUI程序中GDI绘图逻辑实现与用户交互响应的核心问题。压缩包共51个文件包含8个头文件.h定义类结构、7个源码文件.cpp实现OnDraw、鼠标消息处理及图形绘制逻辑、2个图标.ico与位图.bmp资源以及编译生成的可执行文件.exe、调试符号.pdb和工程配置文件.dsw/.dsp整体大小3.69MB完整呈现VC6.0环境下MFC单文档应用的标准目录结构与构建流程。已有396人学习下载读者可直接运行exe体验交互式绘图效果复现从CView继承、CDC设备上下文调用、LineTo/DrawRect/Ellipse绘图函数使用到WM_LBUTTONDOWN消息映射的全流程代码掌握颜色设置、坐标变换等进阶绘图控制要点。1. 这不是“画图软件”而是 Windows 桌面程序的“手绘底层”MFC 绘制直线、矩形、椭圆到底在干啥你有没有试过点开一个老式 Windows 软件——比如某个设备控制面板、实验室数据采集工具或者十年前的工业配置界面——里面按钮是灰蓝色的窗口边框带阴影菜单栏下拉时有淡入效果而界面上还实时画着一条随传感器跳动的曲线那条线很可能就是用 MFCMicrosoft Foundation Classes一笔一笔“画”出来的。它不是 Photoshop 里拖个椭圆工具就完事也不是网页上写个canvas就能跑它是让程序员像“手艺人”一样直接调用 Windows 系统最底层的绘图能力在窗口客户区里一像素一像素地安排线条走向、填充颜色、响应鼠标拖拽。你今天看到的“绘制直线、矩形、椭圆”表面是三个几何图形背后其实是整套 Windows 桌面程序图形交互的最小可行入口——没有窗体框架、没有 UI 库封装、没有跨平台抽象只有你和 GDIGraphics Device Interface之间的一张画布、一支笔、一个坐标系。适合谁刚学完 C 基础、对“程序怎么在屏幕上显示东西”还停留在cout阶段的同学想补全传统桌面开发逻辑、看懂遗留工业软件源码的转岗工程师或者单纯想亲手造一个“能画、能擦、能存”的迷你绘图板不靠 Electron、不靠 Qt就用原生 Windows 的方式。这不是玄学是看得见、改得动、断点跟得进的实在功夫。2. 先搞懂三件事为什么非得用 MFC为什么非得重写 OnDraw为什么坐标系总“反着来”2.1 MFC 不是语言是“Windows 图形世界的翻译官”很多新手第一反应是“C 我会Python 我会为啥还要学 MFC”因为 C 本身不会画图——它连“窗口”都没有概念。Windows 系统提供了一套叫 Win32 API 的底层函数比如CreateWindowEx、BeginPaint、LineTo但全是 C 风格的指针、句柄、结构体写十行代码光声明变量就得五种类型。MFC 就是微软给这套“天书”配的中文说明书自动翻译器它把窗口封装成CWnd类把画布封装成CDCDevice Context类把鼠标消息封装成OnLButtonDown这样的成员函数。你不用再手动管理HDC句柄生命周期也不用每次画线前都调BeginPaint/EndPaint——MFC 在背后帮你扛了。打个比方Win32 是你要亲自拧螺丝、接电线、读电路图才能点亮一盏灯MFC 是给你一个带开关、插头、LED 指示灯的台灯套装——你只管按开关它自动完成所有底层动作。学 MFC本质是学“怎么用面向对象的方式安全、可维护地调用 Windows 原生绘图能力”。2.2 OnDraw 不是“画一次”而是“系统喊你重画时才动笔”新手常犯的错在OnInitDialog()里写pDC-Rectangle(10,10,100,100)结果窗口一缩放、一遮挡再露出来矩形就消失了。原因很简单OnDraw(CDC* pDC)不是你“想画就画”的画布而是 Windows 的“重绘委托协议”。当系统发现某块窗口区域变脏比如被别的窗口盖住后又暴露、用户拖动了窗口边框它会主动调用你的OnDraw并传给你一块“干净画布”pDC。你只负责在这块画布上把当前该显示的内容画全画完系统收走画布下次再脏再给你一块新的。所以所有绘制逻辑必须塞进OnDraw而不是按钮点击事件里直接画。按钮点击该做的事是记录“用户想画一个矩形”存下起点、终点坐标然后调用Invalidate()告诉系统“我这块区域脏了请重绘”——接下来系统自然会调OnDraw你再从内存里取出坐标画出来。这是 MFC 绘图的铁律数据驱动视图而非操作直接绘图。2.3 坐标系不是数学课本里的是 Windows 的“左上原点世界”你在数学课上学的坐标系原点在中心X 向右为正Y 向上为正。Windows GDI 的默认坐标系原点在左上角X 向右为正Y向下为正。这意味着Rectangle(0,0,100,100)画的是从左上角开始、宽 100 像素、高 100 像素的矩形Ellipse(50,50,150,150)画的是以 (50,50) 为左上角、(150,150) 为右下角的外切矩形内的椭圆如果你想让 Y 轴“向上为正”得手动调SetMapMode(MM_LOENGLISH)或SetWindowExtEx但绝大多数项目不这么干——因为所有 Windows 窗口、控件、字体度量都基于这个左上原点体系强行改反而容易翻车。记住这个口诀“Windows 的 Y 轴是重力方向”。你画的每一条线、每一个点都要先在脑子里把坐标系“倒过来”想一遍。这是新手最常卡壳的“认知摩擦点”不是你算错了是坐标系默认就和你直觉相反。3. 第一个能跑通的例子从新建工程到画出第一个红色矩形含完整步骤与逐行解释3.1 新建 MFC 应用程序选“单文档”关掉所有高级选项打开 Visual Studio2019 或更新版本点击【创建新项目】→ 搜索 “MFC 应用程序” → 选择模板 → 输入项目名如MyFirstDrawer→ 点击【下一步】。关键设置应用程序类型选单文档Single document高级功能全部取消勾选不选数据库、不选 ActiveX、不选打印预览用户界面功能只保留工具栏和状态栏其他如“拆分窗口”“OLE 容器”全关最后一步确认“使用 Unicode 库”已勾选现代 Windows 开发标准。提示选“单文档”是因为它自动生成了标准的CView视图类而绘图逻辑就写在视图里如果选“基于对话框”你会被困在对话框资源编辑器里找不到OnDraw入口新手极易迷失。3.2 找到并打开CMyFirstDrawerView.cpp你的画布就在这个文件里项目生成后在【解决方案资源管理器】中展开Source Files→ 找到MyFirstDrawerView.cpp类名会匹配你项目名如CMyFirstDrawerView。双击打开。滚动到文件末尾找到这个函数void CMyFirstDrawerView::OnDraw(CDC* pDC) { CMyFirstDrawerDoc* pDoc GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; // TODO: add draw code for native data here }这就是你的“法定画布”。现在我们往// TODO后面加第一行真正绘图代码。3.3 写下第一行绘图代码画一个红色矩形并理解每个参数含义在// TODO下方插入以下代码注意不要删掉原有ASSERT和ifvoid CMyFirstDrawerView::OnDraw(CDC* pDC) { CMyFirstDrawerDoc* pDoc GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; // ★★★ 第一行真正绘图代码 ★★★ CRect rect(50, 50, 200, 150); // 定义矩形区域左50, 上50, 右200, 下150 CPen pen(PS_SOLID, 2, RGB(255, 0, 0)); // 创建一支红色实线笔粗2像素 CBrush brush(RGB(255, 220, 220)); // 创建一个浅红色填充刷 CPen* pOldPen pDC-SelectObject(pen); // 把笔“装上”画布 CBrush* pOldBrush pDC-SelectObject(brush); // 把刷“装上”画布 pDC-Rectangle(rect); // 真正画矩形 pDC-SelectObject(pOldPen); // 画完换回原来的笔重要 pDC-SelectObject(pOldBrush); // 画完换回原来的刷重要 }逐行白话解释CRect rect(50, 50, 200, 150);定义一个矩形区域。注意顺序是(left, top, right, bottom)不是(x, y, width, height)。这里画的是从 X50、Y50 开始到 X200、Y150 结束的矩形实际宽150 像素高100 像素。CPen pen(PS_SOLID, 2, RGB(255, 0, 0));创建一支笔。“PS_SOLID”表示实线“2”是线宽像素“RGB(255,0,0)”是纯红R255, G0, B0。RGB 值范围都是 0~255。CBrush brush(RGB(255, 220, 220));创建一个填充刷。这里用浅红色粉红让矩形内部不是空心。如果想画空心矩形这行可以删但下面SelectObject(brush)也要删。pDC-SelectObject(pen);把这支笔“安装”到画布上。就像你换钢笔写字前得先把旧笔拔下来、新笔插进去。SelectObject返回旧笔指针我们存到pOldPen里就是为了后面换回去。pDC-Rectangle(rect);核心命令告诉画布“按我给的矩形区域用当前笔和刷画一个矩形”。它自动画边框 填充。pDC-SelectObject(pOldPen);画完立刻换回原来的笔。这步绝不能省因为pDC是系统共享资源如果你不换回去后续系统画菜单、画按钮时可能用你的粗红线整个界面就乱了——这是新手最典型的“界面崩溃”原因。3.4 编译运行看到红色矩形才算真正入门按Ctrl F5不调试直接运行等待几秒窗口弹出。你将看到一个标准 Windows 单文档窗口标题栏、菜单栏、工具栏、状态栏以及——在客户区中央一个清晰的红色矩形边框粗、内部浅红。如果没看到检查是否在OnDraw里写了代码不是在OnInitialUpdate或按钮函数里检查CRect四个值是否合理比如right left会导致矩形消失检查RGB参数是否写反RGB(0,0,255)是蓝不是红。看到它的那一刻你就跨过了 MFC 绘图的第一道门槛你亲手把代码变成了屏幕上的图形。这不是 Demo是真实 Windows 程序的毛细血管级操作。4. 从矩形到椭圆三步扩展法让第一个例子活起来支持鼠标拖拽画图4.1 思路拆解把“固定坐标”变成“鼠标动态坐标”刚才的矩形是写死的(50,50,200,150)。要让它随鼠标画就得记录鼠标按下时的起点OnLButtonDown记录鼠标移动时的临时终点OnMouseMove并实时重绘Invalidate()鼠标松开时把最终坐标存下来作为永久图形OnLButtonUp。我们先实现“鼠标按下→移动→松开画一个椭圆”再逐步加入直线、矩形切换。4.2 在视图类中添加成员变量存起点、终点、当前绘图模式打开MyFirstDrawerView.h头文件在public:区域下方、protected:上方添加如下成员变量public: enum DrawMode { MODE_NONE, MODE_ELLIPSE, MODE_RECTANGLE, MODE_LINE }; DrawMode m_drawMode; // 当前绘图模式 CPoint m_ptStart; // 鼠标按下时的起点 CPoint m_ptEnd; // 鼠标移动/松开时的终点 bool m_bDrawing; // 是否正在拖拽中用于 OnMouseMove 判断然后回到MyFirstDrawerView.cpp在构造函数CMyFirstDrawerView::CMyFirstDrawerView()里初始化它们CMyFirstDrawerView::CMyFirstDrawerView() { m_drawMode MODE_NONE; m_bDrawing FALSE; }4.3 实现鼠标消息响应三步钩子让图形跟着鼠标跑在MyFirstDrawerView.cpp中右键 → 【类向导】→ 选择CMyFirstDrawerView→ 左侧选Message→ 找到WM_LBUTTONDOWN→ 双击添加OnLButtonDown同理添加OnMouseMove和OnLButtonUp。然后填入以下代码void CMyFirstDrawerView::OnLButtonDown(UINT nFlags, CPoint point) { m_ptStart point; // 记下起点 m_ptEnd point; // 初值设为起点 m_bDrawing TRUE; // 标记开始拖拽 m_drawMode MODE_ELLIPSE; // 默认画椭圆可后续改成按钮切换 CView::OnLButtonDown(nFlags, point); } void CMyFirstDrawerView::OnMouseMove(UINT nFlags, CPoint point) { if (m_bDrawing (nFlags MK_LBUTTON)) { m_ptEnd point; // 更新终点为当前鼠标位置 Invalidate(); // 告诉系统客户区脏了快重绘 } CView::OnMouseMove(nFlags, point); } void CMyFirstDrawerView::OnLButtonUp(UINT nFlags, CPoint point) { if (m_bDrawing) { m_ptEnd point; // 最终确定终点 m_bDrawing FALSE; // 结束拖拽 // 此处可添加“保存到图形列表”逻辑本例暂不存只画一次 } CView::OnLButtonUp(nFlags, point); }4.4 改写 OnDraw根据模式画不同图形支持“橡皮筋”效果回到OnDraw函数把原来固定的矩形代码替换成动态分支void CMyFirstDrawerView::OnDraw(CDC* pDC) { CMyFirstDrawerDoc* pDoc GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; // ★★ 动态绘图主逻辑 ★★ if (m_bDrawing) { // 正在拖拽时画“橡皮筋”效果虚线预览 CPen pen(PS_DOT, 1, RGB(0, 0, 255)); // 蓝色虚线 CPen* pOldPen pDC-SelectObject(pen); CRect rect(m_ptStart, m_ptEnd); // 自动按左上/右下排序 switch (m_drawMode) { case MODE_ELLIPSE: pDC-Ellipse(rect); break; case MODE_RECTANGLE: pDC-Rectangle(rect); break; case MODE_LINE: pDC-MoveTo(m_ptStart); pDC-LineTo(m_ptEnd); break; } pDC-SelectObject(pOldPen); } // ★★ 此处可添加“已保存图形”的循环绘制后续扩展★★ }注意CRect(m_ptStart, m_ptEnd)构造函数会自动处理坐标大小关系比如m_ptStart.y m_ptEnd.y时它会把top设为m_ptEnd.y所以你无需手动min/max放心传。编译运行点击窗口任意位置并拖动鼠标——你会看到一条蓝色虚线椭圆随着鼠标移动实时变化大小。松开鼠标虚线消失图形定格。这就是最基础的“所见即所得”绘图体验。你已经把静态示例升级成了可交互的原型。5. 新手必踩的五大坑从黑屏、闪退到坐标错乱血泪经验总结5.1 现象窗口一片空白或只显示灰色背景什么图形都不见原因OnDraw函数里忘了调CView::OnDraw(pDC)父类实现或误删了ASSERT_VALID(pDoc)后的return语句导致pDC为空指针。解决检查OnDraw开头三行是否完整存在确保if (!pDoc) return;没被注释或删除在pDC-Rectangle(...)前加一句if (!pDC) return;做双重保险。5.2 现象画完图形窗口一最小化再恢复图形就消失了原因把绘图代码写在了OnInitialUpdate、OnCreate或按钮响应函数里而不是OnDraw。这些函数只执行一次系统重绘时不调用。解决所有绘图逻辑必须在OnDraw内按钮函数只负责修改数据如m_drawMode MODE_LINE和触发重绘Invalidate()。5.3 现象图形位置完全不对比如想画在中间结果跑到右上角去了原因混淆了CRect的(left, top, right, bottom)和(x, y, width, height)。例如写了CRect(100, 100, 50, 50)由于right left矩形面积为负GDI 直接忽略绘制。解决永远用CRect(CPoint pt1, CPoint pt2)构造让 MFC 自动排序或手动确保left right top bottom用min/max包裹CRect(min(x1,x2), min(y1,y2), max(x1,x2), max(y1,y2))。5.4 现象画线时出现“残影”鼠标移动留下多条线像鬼画符原因在OnMouseMove里直接调用了pDC-LineTo()而pDC在OnMouseMove中不可用它只在OnDraw中有效。OnMouseMove里只能更新坐标、调Invalidate()不能直接绘图。解决删掉OnMouseMove里所有pDC-xxx代码确保绘图只发生在OnDrawInvalidate()后系统会自动调OnDraw这才是唯一合法绘图时机。5.5 现象程序运行几秒后崩溃报错Access violation reading location 0x00000000原因SelectObject后没换回原对象且CPen/CBrush对象是栈变量如CPen pen(...)函数退出后自动析构但画布pDC还拿着已销毁对象的指针。下次OnDraw再用就访问野指针。解决两种方案任选其一方案 A推荐用new创建堆对象并在类中声明为成员变量如CPen* m_pPen;在OnDraw中pDC-SelectObject(m_pPen)不换回因为成员变量一直有效方案 B严格遵守“先存旧、再换新、最后换回”三步且CPen/CBrush必须是局部变量栈上确保SelectObject(pOldPen)在函数结束前执行。6. 下一步学什么从“画三个图形”到“做一个能存能开的绘图板”我的实战路径建议6.1 第二阶段让图形真正“留下来”不再只是橡皮筋你现在画的椭圆松开鼠标就没了。要让它成为永久图形需要引入“图形对象列表”。这不是加几行代码的事而是一次小架构升级定义一个基类CGraphicObject含纯虚函数Draw(CDC* pDC)派生CEllipseObject、CRectangleObject、CLineObject各自实现Draw在视图类中加std::vectorstd::unique_ptrCGraphicObject m_objectsOnLButtonUp时根据m_drawMode创建对应对象push_back进列表OnDraw中遍历m_objects对每个对象调obj-Draw(pDC)。这样你就能无限添加图形关闭再打开也不会丢——因为数据存在内存里了。这是从“Demo”迈向“可用工具”的关键跃迁。6.2 第三阶段支持撤销、保存、打开补齐生产级功能有了图形列表下一步就是持久化功能关键技术点新手友好度撤销Undo用std::stackstd::vectorstd::unique_ptrCGraphicObject m_undoStack每次操作前push当前状态点击撤销时pop并替换m_objects⭐⭐⭐⭐保存为 .draw 文件用CFile二进制写入先写图形数量再对每个图形写typeint、points4个 int存矩形/椭圆的LTRB或线的2个点⭐⭐⭐打开 .draw 文件用CFile读取按相同格式解析重建m_objects列表最后Invalidate()⭐⭐⭐提示.draw是自定义后缀不用注册关联纯文本或二进制都行。我第一次做时先用文本格式每行ELLIPSE 50 50 200 150方便调试稳定后再切二进制提速。6.3 第四阶段加入实用细节告别“玩具感”真实绘图工具的质感藏在细节里抗锯齿在OnDraw开头加pDC-SetStretchBltMode(COLORONCOLOR); pDC-SetGraphicsMode(GM_ADVANCED);再用Gdiplus::Graphics替代CDC需初始化 GDI颜色/线宽选择拖一个CColorDialog出来让用户点选用CComboBox下拉选线宽1,2,3,5,8缩放和平移监听CtrlMouseWheel触发SetWindowExt/SetViewportExt配合ScrollWindow实现平移图层概念把m_objects拆成m_backgroundObjects和m_foregroundObjects支持“置顶”“置底”右键菜单。这些不是炫技而是当你把程序给同事或老师看时他们脱口而出“这真能用啊”的底气来源。从那以后我每次教新人都强制他们做完“鼠标拖拽画椭圆”后立刻动手加一个“保存按钮”。不是为了功能完整而是为了建立一种肌肉记忆图形是数据不是画面保存的本质是把内存里的对象序列化成文件字节。只要这个闭环打通了后面学 Qt、学 WPF、甚至学 WebGL你都会下意识先问“它的图形对象模型长什么样数据怎么存”——而不是盯着 API 文档发呆。希望帮到你。本文还有配套的精品资源点击获取
企业数字化 ERP 产品动态
相关推荐
龙呤AI 1.5本地私有化部署实战:轻量级大模型离线智能助手搭建指南 前两个月我把家里的旧迷你主机翻出来,想做一个真正属于自己、断网也能用的智能助手。市面上云端的语音助手响应快,但数据和隐私总归不在自己手里;完全本地跑的大模型又动不动要吃几十GB显存。后来我盯上了龙呤AI 1.5这套本地轻量化智能交互系… · 2026/11/4 14:13:13
用Codex与剪映Skill打造全自动视频剪辑流水线 做了大半年视频剪辑,我最高频的操作就是拖素材、切静音、删废镜头、加转场。尤其碰到访谈类和口播类视频,一条三五分钟的素材,静音段、停顿、重复语气词能占三分之一时长,逐条剪又慢又无聊。后来我把Codex和剪映Skill组合起来&… · 2026/11/4 14:13:13
链表局部反转算法:头插法实现与优化 1. 问题背景与核心挑战 链表局部反转是算法面试中的经典问题,LeetCode 92题要求我们在单链表中仅反转从位置left到right的部分。这个问题看似简单,但实际处理时存在几个关键难点: 边界处理复杂 :当left1时,意味着需要… · 2026/11/4 14:57:33
智能API生成技术:提升开发效率与接口性能 1. 接口设计的现状与挑战 最近在重构公司支付网关时,我对着十几个版本的API文档陷入了沉思。每次业务调整都要手动维护Swagger文档、修改参数校验逻辑、更新测试用例,这种重复劳动消耗了团队近30%的开发时间。更头疼的是,不同客户端开发者对同… · 2026/11/4 14:57:33
Ghidra 9.0.2逆向分析:JDK11环境、headless批处理与反编译判读 简介:Ghidra 9.0.2 是面向网络安全分析人员、漏洞研究者与恶意软件分析学习者的开源逆向工程平台,由 NSA 研究理事会设计维护,可用于对已编译二进制进行反汇编、控制流梳理与潜在漏洞定位。其图形界面支持浏览和修改控制流图,反汇… · 2026/11/4 14:57:33
小米MiMo-V2.6开源旗舰实测:多模态3D能力与API排队问题解析 1. 凌晨那场发布,我盯完了全程 小米选在凌晨发 MiMo-V2.6 系列,这个时间点本身就挺有意思。做模型发布的人都知道,凌晨发要么是抢一个时间窗口,要么是团队刚跑完最后一轮压测,来不及等白天。我第一时间把开源仓库拉下来… · 2026/11/4 14:57:33
HammerDB六库TPC-C横向对比:从跑分读数到选型决策 数据库选型这件事,最怕的就是拿一张跑分表当决策依据。我用 HammerDB 做过不少轮横向对比,六个主流关系型数据库放在同一套硬件上跑 TPC-C,结论经常和厂商宣传、社区口碑对不上:有的库单看峰值很漂亮,稳态却掉得厉害&a… · 2026/11/4 14:57:33
带外管理网建设指南:选型、布线、配置与隔离验证 1. 为什么要把管理口单独拉一张网很多机房里都存在这样的场景:机柜里十几台设备堆着,业务网段跑得好好的,某天核心设备配置出错断了网,人只能抱着笔记本冲到机房,插上串口线慢慢敲命令。或者更尴尬的是,业务… · 2026/11/4 14:56:32
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 6:59:29
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 7:02:38
AI辅助技术栈评估:提升研发决策效率60% 1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年… · 2026/11/4 0:00:17
从生成Token到直接决策:Jev如何重塑AI Agent工程实践 1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你… · 2026/11/4 0:00:17
32G统一内存跑大模型:内存账、TPS实测与端云分流 想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统… · 2026/11/4 0:00:17
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 3:16:49
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 6:59:29
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/4 7:02:38