Skip to content

Commit a495a69

Browse files
committed
Enforce Windows header order and update examples
Added documentation and code changes to ensure windows.h is included before shellapi.h in Windows platform files, with clang-format disabled for header ordering. Updated keyboard example output to remove emoji for consistency. Fixed COM initialization flag in application_windows.cpp and switched to LoadImageW for wide string icon loading.
1 parent e3da945 commit a495a69

File tree

3 files changed

+44
-10
lines changed

3 files changed

+44
-10
lines changed

.cursor/rules/platform-implementation.mdc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ Each platform file defines the `Impl` class declared in the cross-platform heade
4343
#### Windows Example ([platform/windows/window_windows.cpp](mdc:src/platform/windows))
4444

4545
```cpp
46+
// clang-format off
4647
#include <windows.h>
48+
#include <shellapi.h>
49+
// clang-format on
4750
#include "../../window.h"
4851

4952
namespace nativeapi {
@@ -279,7 +282,10 @@ Managers also use PIMPL for platform event monitoring:
279282

280283
```cpp
281284
// window_manager_windows.cpp
285+
// clang-format off
282286
#include <windows.h>
287+
#include <shellapi.h>
288+
// clang-format on
283289
#include "../../window_manager.h"
284290

285291
namespace nativeapi {
@@ -543,6 +549,32 @@ Use example applications for manual testing:
543549
- [examples/menu_example/](mdc:examples/menu_example)
544550
- [examples/tray_icon_example/](mdc:examples/tray_icon_example)
545551

552+
## Windows Platform Header Rules
553+
554+
For all Windows platform implementation files, follow these header inclusion and formatting rules:
555+
556+
### Header Ordering
557+
558+
Always include `windows.h` before `shellapi.h`:
559+
560+
```cpp
561+
// clang-format off
562+
#include <windows.h>
563+
#include <shellapi.h>
564+
// clang-format on
565+
```
566+
567+
### Formatting Control
568+
569+
Use `// clang-format off` and `// clang-format on` comments to disable automatic formatting for Windows-specific includes. This prevents formatters from reordering platform-specific headers that must be included in a specific order.
570+
571+
### Rationale
572+
573+
- `windows.h` defines fundamental Windows types and macros
574+
- `shellapi.h` depends on definitions from `windows.h`
575+
- Header order matters for Windows API compilation
576+
- Disabling formatting preserves the required inclusion order
577+
546578
## Best Practices
547579

548580
1. **Validate handles** - Always check for null/nil/nullptr before using
@@ -552,6 +584,7 @@ Use example applications for manual testing:
552584
5. **Keep implementations similar** - Same structure across platforms for maintainability
553585
6. **Document platform quirks** - Note any platform-specific behavior differences
554586
7. **Test thoroughly** - Each platform has unique edge cases
587+
8. **Follow Windows header ordering** - Always include `windows.h` before `shellapi.h` with formatting disabled
555588

556589
## Common Pitfalls
557590

examples/keyboard_example/main.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,24 +69,24 @@ int main() {
6969
// Create keyboard monitor
7070
g_monitor = native_keyboard_monitor_create();
7171
if (!g_monitor) {
72-
std::cout << "Failed to create keyboard monitor\n";
72+
std::cout << "Failed to create keyboard monitor\n";
7373
return 1;
7474
}
75-
std::cout << "Keyboard monitor created successfully\n";
75+
std::cout << "Keyboard monitor created successfully\n";
7676

7777
// Set up callbacks
7878
if (!native_keyboard_monitor_set_callbacks(
7979
g_monitor, on_key_pressed, on_key_released, on_modifier_keys_changed,
8080
nullptr)) {
81-
std::cout << "Failed to set callbacks\n";
81+
std::cout << "Failed to set callbacks\n";
8282
native_keyboard_monitor_destroy(g_monitor);
8383
return 1;
8484
}
85-
std::cout << "Callbacks set successfully\n";
85+
std::cout << "Callbacks set successfully\n";
8686

8787
// Start monitoring
8888
if (!native_keyboard_monitor_start(g_monitor)) {
89-
std::cout << "Failed to start keyboard monitoring\n";
89+
std::cout << "Failed to start keyboard monitoring\n";
9090
native_keyboard_monitor_destroy(g_monitor);
9191
return 1;
9292
}

src/platform/windows/application_windows.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
#include <shellapi.h>
1+
// clang-format off
22
#include <windows.h>
3+
#include <shellapi.h>
4+
// clang-format on
35
#include <iostream>
46
#include <string>
57
#include <vector>
@@ -17,8 +19,7 @@ class Application::Impl {
1719

1820
bool Initialize() {
1921
// Initialize COM
20-
HRESULT hr =
21-
CoInitializeEx(nullptr, COINIT_APPMODEL | COINIT_DISABLE_OLE1DDE);
22+
HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
2223
if (FAILED(hr)) {
2324
return false;
2425
}
@@ -100,9 +101,9 @@ class Application::Impl {
100101
// Convert to wide string
101102
std::wstring wide_path(icon_path.begin(), icon_path.end());
102103

103-
// Load icon from file
104+
// Load icon from file using LoadImageW for wide strings
104105
HICON icon =
105-
static_cast<HICON>(LoadImage(nullptr, wide_path.c_str(), IMAGE_ICON, 0,
106+
static_cast<HICON>(LoadImageW(nullptr, wide_path.c_str(), IMAGE_ICON, 0,
106107
0, LR_LOADFROMFILE | LR_DEFAULTSIZE));
107108

108109
if (!icon) {

0 commit comments

Comments
 (0)