win32/embedded_manifest Windows
Overview
Embedded manifest example
Windows executables can contain manifests. Manifests are metadata can control various aspects before and during program execution. The most common use cases are:
- UAC awareness (for privilege escalation)
- DPI awareness (for correctly rendering at >96 dpi)
- Enabling visual styles (Common Controls v6)
This example uses the manifest to enable visual styles, which will affect the appearance of a button.
Embedding manifests with Odin
Manifests are regular embedded resources (such as images or localized strings),
so they can be embedded with a .rc script. They use resource type
RT_MANIFEST (numeric value 24), and the main application manifest is
expected to have resource ID 1.
See the contents of resource.rc and compile with:
odin build . -resource:resource.rc
Alternatively, a manifest can be embedded into an existing binary with the mt.exe
tool, which is part of the Windows SDK:
mt.exe -manifest app.manifest -outputresource:embedded_manifest.exe;1
Troubleshooting
If you are seeing:
error RC1015: cannot open include file 'winuser.h'
Your build environment is not set up properly for rc.exe, which is the component
that compiles the resource.rc file. The easiest fix is to launch the developer
command prompt for Visual Studio, and build from there.
Alternatively, you must manually ensure that your local Windows SDK's appropriate
Include directory is added to your %INCLUDE% envrionment variable.
Code
main.odin ¶71 linesSource
1package manifest_example
2
3import runtime "base:runtime"
4import win "core:sys/windows"
5
6main :: proc() {
7 instance := win.HINSTANCE(win.GetModuleHandleW(nil))
8 assert(instance != nil, "Failed to fetch current instance")
9 CLASS_NAME :: "ManifestExampleWindow"
10
11 startup_info : win.STARTUPINFOW
12 win.GetStartupInfoW(&startup_info)
13 nCmdShow := (startup_info.dwFlags & win.STARTF_USESHOWWINDOW) != 0 ? cast(win.c_int)startup_info.wShowWindow : win.SW_SHOWDEFAULT
14
15 cls := win.WNDCLASSW {
16 lpfnWndProc = wndproc,
17 lpszClassName = CLASS_NAME,
18 hInstance = instance,
19 hCursor = win.LoadCursorA(nil, win.IDC_ARROW),
20 hbrBackground = win.GetSysColorBrush(win.COLOR_3DFACE),
21 }
22
23 class := win.RegisterClassW(&cls)
24 assert(class != 0, "Class creation failed")
25
26 hwnd := win.CreateWindowW(CLASS_NAME,
27 "Manifest example",
28 win.WS_OVERLAPPEDWINDOW,
29 win.CW_USEDEFAULT, 0, 800, 600,
30 nil, nil, instance, nil)
31
32 assert(hwnd != nil, "Window creation failed")
33
34 win.ShowWindow(hwnd, nCmdShow)
35 win.UpdateWindow(hwnd)
36
37 msg: win.MSG
38
39 for win.GetMessageW(&msg, nil, 0, 0) > 0 {
40 win.TranslateMessage(&msg)
41 win.DispatchMessageW(&msg)
42 }
43}
44
45wndproc :: proc "system"(hwnd: win.HWND, msg: win.UINT, wparam: win.WPARAM, lparam: win.LPARAM) -> win.LRESULT {
46 switch msg {
47 case win.WM_CREATE:
48 context = runtime.default_context()
49 // Create a button to demonstrate the visual effect of Common Controls v6.
50 button := win.CreateWindowExW(0, "BUTTON", "",
51 win.WS_CHILD | win.WS_VISIBLE,
52 10, 10, 150, 30,
53 hwnd, nil, nil, nil)
54 assert(button != nil, "Button creation failed")
55
56 // In addition to the change in visual appearance of the button we just created,
57 // we *attempt* to detect programmatically whether we've successfully linked to Common Controls v6.
58 // However, this is not an intended use case, so it may or may not work reliably on your system.
59 // Do NOT use this in production code.
60 if win.GetWindowTheme(button) != nil {
61 // Common Controls v6 is probably linked successfully.
62 win.SetWindowTextW(button, "Modern button")
63 } else {
64 // Common Controls v6 is probably not linked successfully.
65 win.SetWindowTextW(button, "Dated button")
66 }
67 case win.WM_DESTROY:
68 win.PostQuitMessage(0)
69 }
70 return win.DefWindowProcW(hwnd, msg, wparam, lparam)
71}
Other Files
app.manifest ¶14 linesSource
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"/>
</dependentAssembly>
</dependency>
</assembly>
resource.rc ¶3 linesSource
#include <winuser.h>
1 RT_MANIFEST "app.manifest"
Declarations Used 37
- base:runtime default_context
- core:sys/windows c_int · COLOR_3DFACE · CreateWindowExW · CreateWindowW · CW_USEDEFAULT · DefWindowProcW · DispatchMessageW · GetMessageW · GetModuleHandleW · GetStartupInfoW · GetSysColorBrush · GetWindowTheme · HINSTANCE · HWND · IDC_ARROW · LoadCursorA · LPARAM · LRESULT · MSG · PostQuitMessage · RegisterClassW · SetWindowTextW · ShowWindow · STARTF_USESHOWWINDOW · STARTUPINFOW · SW_SHOWDEFAULT · TranslateMessage · UINT · UpdateWindow · WM_CREATE · WM_DESTROY · WNDCLASSW · WPARAM · WS_CHILD · WS_OVERLAPPEDWINDOW · WS_VISIBLE