Githu: https://github.com/vladelaina/Catime

作者是一个高度依赖计时器功能的人,但是市面上的软件都不能满足个性化的需求,所以打算自己动手开发,同时采用c语言来做原生开发,一下是开发思路,以及遇到的问题

1. 原生开发的优势

使用Windows API进行原生开发具有以下优势:

  • 高性能:直接调用系统API,无中间层开销,执行效率高
  • 低资源占用:程序体积小,内存占用少,适合轻量级应用
  • 系统集成度高:可以深度访问Windows系统功能和资源
  • 无依赖性:不需要额外运行时环境,降低部署复杂度
  • 精确控制:对UI和系统交互有更精细的控制能力

2. 开发思路与架构设计

2.1 基本架构

典型的Windows API应用程序架构包括:

  • 窗口过程函数:处理窗口消息的核心回调函数
  • 消息循环:获取并分发系统消息
  • 资源管理:处理GDI对象、内存等资源
  • 模块化设计:将功能分散到不同模块中

2.2 设计模式

  • 事件驱动模型:基于Windows消息机制
  • MVC/MVP模式:分离UI和业务逻辑
  • 单例模式:管理全局资源和状态

3. 关键技术点

3.1 窗口创建与管理

// 窗口类注册
WNDCLASS wc = {0};
wc.lpfnWndProc = WindowProcedure;
wc.hInstance = hInstance;
wc.lpszClassName = "MyWindowClass";
RegisterClass(&wc); // 创建窗口
HWND hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
"MyWindowClass",
"Window Title",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 800, 600,
NULL, NULL, hInstance, NULL);

3.2 消息处理

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
switch(msg) {
case WM_CREATE:
// 窗口创建时的初始化
break;
case WM_PAINT:
// 绘制窗口内容
break;
case WM_COMMAND:
// 处理菜单和控件命令
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}

3.3 GDI绘图

void DrawContent(HWND hwnd) {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps); // 创建和选择画笔、画刷
HPEN hPen = CreatePen(PS_SOLID, 1, RGB(0, 0, 255));
HPEN hOldPen = SelectObject(hdc, hPen); // 绘制图形
Rectangle(hdc, 10, 10, 100, 100); // 清理资源
SelectObject(hdc, hOldPen);
DeleteObject(hPen); EndPaint(hwnd, &ps);
}

3.4 资源管理

// 资源文件 (resource.rc)
IDI_MYICON ICON "myicon.ico"
IDM_MYMENU MENU BEGIN
POPUP "&File"
BEGIN
MENUITEM "&Open", IDM_OPEN
MENUITEM "&Save", IDM_SAVE
MENUITEM SEPARATOR
MENUITEM "E&xit", IDM_EXIT
END
END // 加载资源
HICON hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MYICON));
SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);

3.5 对话框和控件

// 创建控件
HWND hButton = CreateWindow(
"BUTTON", "Click Me",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
10, 10, 100, 30,
hwnd, (HMENU)IDC_BUTTON, hInstance, NULL); // 显示对话框
DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG), hwnd, DialogProc); // 对话框过程
INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
switch(msg) {
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if(LOWORD(wParam) == IDOK) {
EndDialog(hwndDlg, IDOK);
return TRUE;
}
break;
}
return FALSE;
}

4. 开发挑战与解决方案

4.1 内存管理

  • 挑战:手动管理内存容易导致泄漏
  • 解决方案
    • 使用资源获取即初始化(RAII)模式
    • 成对调用分配/释放函数
    • 使用工具检测内存泄漏

4.2 多线程同步

  • 挑战:UI线程与工作线程的协调
  • 解决方案
    • 使用PostMessage/SendMessage进行线程间通信
    • 合理使用互斥量、事件、信号量等同步原语
    • 避免死锁和竞态条件

4.3 DPI感知

  • 挑战:在不同DPI设置下保持UI一致性
  • 解决方案
    • 实现DPI感知(SetProcessDpiAwareness)
    • 使用相对单位而非固定像素
    • 根据DPI缩放绘图操作

4.4 国际化支持

  • 挑战:支持多语言和不同区域设置
  • 解决方案
    • 使用资源字符串而非硬编码文本
    • 支持Unicode字符集
    • 考虑文本布局方向(RTL/LTR)

5. 构建与部署

5.1 构建工具

  • Visual Studio:提供完整IDE体验
  • MinGW/GCC:开源编译器选项
  • CMake:跨平台构建系统
  • Makefile:传统构建脚本

5.2 静态链接与动态链接

  • 静态链接:生成独立可执行文件,无外部依赖
  • 动态链接:减小可执行文件体积,共享系统DLL

5.3 安装程序制作

  • NSIS (Nullsoft Scriptable Install System)
  • Inno Setup
  • WiX Toolset

5.4 部署注意事项

  • 运行时依赖检查
  • 权限要求
  • 注册表和系统配置
  • 应用程序清单(manifest)设置

6. 调试与优化技巧

6.1 调试技术

  • 使用DebugView捕获调试输出
  • 使用WinDbg进行高级调试
  • 实现自定义日志系统

6.2 性能优化

  • 减少不必要的重绘
  • 优化GDI对象使用
  • 使用双缓冲技术避免闪烁
  • 延迟加载资源

7. 参考资源

8. 结语

Windows API原生开发虽然学习曲线较陡,但掌握后能够开发出高效、轻量且深度集成Windows系统的应用程序。通过合理的架构设计和模块化,可以降低开发复杂度,提高代码可维护性。

原生开发,使用C语言调用Windows API 开发软件思路分享的更多相关文章

  1. C#调用windows API的一些方法

    使用C#调用windows API(从其它地方总结来的,以备查询) C#调用windows API也可以叫做C#如何直接调用非托管代码,通常有2种方法: 1.  直接调用从 DLL 导出的函数. 2. ...

  2. C#中调用Windows API的要点 .

    介绍 API(Application Programming Interface),我想大家不会陌生,它是我们Windows编程的常客,虽然基于.Net平台的C#有了强大的类库,但是,我们还是不能否认 ...

  3. C#中调用Windows API时的数据类型对应关系

    原文 C#中调用Windows API时的数据类型对应关系 BOOL=System.Int32 BOOLEAN=System.Int32 BYTE=System.UInt16 CHAR=System. ...

  4. VBS调用Windows API函数

    Demon's Blog 忘记了,喜欢一个人的感觉 Demon's Blog  »  程序设计  »  VBS调用Windows API函数 « 用VBS修改Windows用户密码 在VB中创建和使用 ...

  5. C#调用Windows API函数截图

    界面如下: 下面放了一个PictureBox 首先是声明函数: //这里是调用 Windows API函数来进行截图 //首先导入库文件 [System.Runtime.InteropServices ...

  6. 【转】用C#调用Windows API向指定窗口发送

    一.调用Windows API. C#下调用Windows API方法如下: 1.引入命名空间:using System.Runtime.InteropServices; 2.引用需要使用的方法,格式 ...

  7. c# 判断窗体是否永在最前(TopMost),调用windows API

    许多程序都可以把自身的窗体设为最前显示状态,这个可以参考博客c#让窗体永在最前 调用windows api 将窗体设为topmost.那么如何判断桌面上的一个窗体是否为最前显示状态呢,不光是自己的程序 ...

  8. c#让窗体永在最前 调用windows api 将窗体设为topmost

    有时候应用程序需要将一个窗体始终位于屏幕的最前面,即使切换到其它窗体也能看到该窗体,这样的窗体就叫做TopMost窗体. 用C#制作TopMost窗体之前,首先要了解如何声明SetWindowPos函 ...

  9. 善于 调用Windows API

    前一段时间看见别人做的一个自动填写信息并且点击登录的程序,觉得很有意思. 其实就是在程序中调用Windows的API,那么如何调用,下面就做个简单的介绍. 写的简单粗暴, 不喜轻喷. 0.首先引入名称 ...

  10. 用C#调用Windows API向指定窗口发送按键消息 z

    用C#调用Windows API向指定窗口发送 一.调用Windows API. C#下调用Windows API方法如下: 1.引入命名空间:using System.Runtime.Interop ...

随机推荐

  1. .net core 文本比对的一个诡异设计

    9-11 发现的,过久了都忘了,记一下 string s = Encoding.ASCII.GetString(new byte[] { 0x57, 00, 0x49, 00, 0x4e, 00, 0 ...

  2. Qt音视频开发13-mpv录像存储

    一.前言 用mpv来做录像存储,保存视频文件,从来都没有如此的方便,直接设置属性stream-record对应的文件路径即可,我的乖乖,一行代码,如此精简美丽大方,搞得我都不敢相信自己的眼睛,mpv除 ...

  3. Eclipse导入并打开java项目,在“package ***;”左侧提示 Multiple markers at this line,或者在“import java.util.*”左侧提示The import java.util cannot be resolved。

    Eclipse导入并打开java项目,在"package ***:"左侧提示 Multiple markers at this line,或者在"import java. ...

  4. 阿里IM技术分享(四):闲鱼亿级IM消息系统的可靠投递优化实践

    本文由阿里闲鱼技术团队景松分享,原题"到达率99.9%:闲鱼消息在高速上换引擎(集大成)",有修订和改动,感谢作者的分享. 1.引言 在2020年年初的时候接手了闲鱼的IM即时消息 ...

  5. java基础知识回顾之java Thread类学习(四)--线程的状态以及转化使用的方法介绍

    java基础知识回顾之java Thread类学习(十)--线程的状态以及转化使用的方法介绍      线程的概述:         线程是程序的多个执行路径,执行调度的单位,依托于进程存在.线程不仅 ...

  6. HTTP方法-GET对比POST

    什么是 HTTP ? 超文本传输协议(HTTP)的设计目的是保证客户端与服务器之间的通信. HTTP 的工作方式是客户端与服务器之间的请求-应答协议. web 浏览器可能是客户端,而计算机上的网络应用 ...

  7. 包装类(Wrapper) 的使用

    package com.ch.java2; import org.junit.Test; /* * 包装类的使用: * 1.java提供了8种基本数据类型对应的包装类,使得基本数据类型的变量具有类的特 ...

  8. Dotnet程序的内存与垃圾回收

    都知道程序运行时的变量是放在内存里的,从我们学c++ 就知道有析构函数  malloc,还有学c#的时候天天 什么垃圾回收 GC 像背八股文样的 ,但是这个内存究竟能分配多少 没有人想过吧 ,不论做什 ...

  9. 又来新活了!AI电商搜索,或是下一个90亿美元独角兽?

    图源:https://www.shopencore.ai/ 全新体验,大模型驱动的对话式购物搜索. Encore, 由2024年10月成立的美国初创公司开发.定位于二手商品对话式购物搜索,最终目标为个 ...

  10. 一种提升SQL改写效率的方法

    本文分享自天翼云开发者社区<一种提升SQL改写效率的方法>,作者:唐****律 一.背景 SQL改写是数据库产品中使用比较频繁的一个技术,在大多数产品中的调用频率也非常高,通常对性能的需求 ...