Skip to content

Developer Guide

KaiUR edited this page May 7, 2026 · 13 revisions

Developer Guide

Prerequisites

  • LLVM/Clang 17+ — C compiler (clang.exe)
  • Visual Studio 2019+ (or Build Tools for Visual Studio) — provides Windows SDK, rc.exe, and link.exe
  • CMake 3.16+
  • Ninja build system
  • Git
  • Qt Creator (optional, as IDE)

Building

Open a Developer Command Prompt for VS, then:

git clone https://github.com/KaiUR/CatiaMenuWin32
cd CatiaMenuWin32
cmake -S . -B build -G "Ninja" -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang
cmake --build build

The executable is output to build/CatiaMenuWin32.exe.

Qt Creator

  1. Open CMakeLists.txt in Qt Creator
  2. Select a Clang kit configured with the MSVC toolchain
  3. Add -DCMAKE_C_COMPILER=clang to the CMake arguments
  4. Build → Build All

Tip: Launch Qt Creator from a Developer Command Prompt for VS so that rc.exe and the Windows SDK are on the PATH.

CI/CD

The workflow (.github/workflows/release.yml) runs on windows-latest using:

  • ilammy/msvc-dev-cmd — sets up the MSVC environment (Windows SDK, rc.exe, link.exe)
  • LLVM/Clang (pre-installed on windows-latest) as the C compiler
  • Ninja as the build backend

On a tagged release (v*) the workflow additionally:

  1. Builds with -DCMAKE_C_COMPILER=clang -DVERSION_OVERRIDE=<version>
  2. Authenticode-signs CatiaMenuWin32.exe via skymatic/code-sign-action@v1
  3. Commits the incremented build_number.txt back to main
  4. Creates the final versioned tag (e.g. v1.3.11.42) and GitHub Release

Code signing secrets

The following secrets must be set in Settings → Secrets → Actions:

Secret Description
CERTIFICATE Base64-encoded PFX file
PASSWORD PFX password
CERTHASH SHA1 thumbprint of the certificate
CERTNAME Common name of the certificate

Project Structure

src/         C source and header files
res/         Resource files (icons, manifest, resource.rc.in, version.h.in)
docs/        GitHub Pages documentation
.github/     GitHub Actions workflows and issue templates

Key Source Files

File Purpose
main.c / main.h Entry point, WndProc, AppState struct
window.c Window creation, menu, toolbar, layout
tabs.c Custom tab bar, script buttons, filter
paint.c GDI painting, script button rendering, tooltips
sync.c GitHub sync thread, manifest, offline cache
github.c HTTPS requests, JSON parsing, SHA verification
runner.c Script execution, Python detection
meta.c Script header metadata parsing
settings.c Settings load/save, Settings dialog
sources.c Script Sources dialog
prefs.c Favourites, hidden scripts, notes, run counts
help.c In-app help window
updater.c Update checker and auto-update

Versioning

  • Version is determined from the latest Git tag at CMake configure time
  • build_number.txt increments by 2 for local builds, 1 for CI builds
  • Local builds are always one build number ahead of the latest release
  • CI workflow: tag push → build → sign → release → commit build_number.txt back to main

Releasing

  1. Develop on develop branch
  2. Open a pull request to main
  3. Merge the PR
  4. Tag from main: git tag v1.x.x && git push origin v1.x.x
  5. GitHub Actions builds, signs, and creates the release automatically

Code Style

  • C11, Win32 API only — no external libraries
  • Unicode throughout — WCHAR, L"" literals, _snwprintf_s
  • Bounds-safe string ops — always wcsncpy/wcsncat with explicit limits; never wcscpy/wcscat
  • Safe formatted output — always _snwprintf_s with _TRUNCATE; never raw sprintf/swprintf
  • All GDI painting double-buffered
  • All state in global AppState g struct
  • Heap memory for scripts — use Folder_Alloc / Folder_Free / Folder_Push helpers; always free on every exit path
  • Use COL_BG(), COL_TEXT() etc. — never hardcode RGB values
  • Cross-thread communication via PostMessage only

Clone this wiki locally