Skip to content

Commit 32a722a

Browse files
committed
fix up the TOC.
1 parent 9d0597a commit 32a722a

File tree

4 files changed

+80
-47
lines changed

4 files changed

+80
-47
lines changed

book_src/SUMMARY.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
[Introduction](introduction.md)
33

4-
* [Opening a Win32 Window](opening_a_win32_window.md)
5-
* [Win32 Window Cleanup](win32_window_cleanup.md)
6-
4+
* [Opening A Window](opening_a_window.md)
5+
* [Win32](opening_a_window/win32.md)
6+
* [Win32 Cleanup](opening_a_window/win32_cleanup.md)

book_src/opening_a_window.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
# Opening A Window
3+
4+
If we wanna draw a triangle, we have to have some place to *put* a triangle.
5+
6+
Generally (but not always) this means showing it in a graphical window on the screen.
7+
8+
Because operating systems all support more than one drawing API,
9+
and because many drawing APIs can be used with more than one operating system,
10+
we're going to separate the lessons about opening a window from the lessons about using a particular drawing API.

book_src/opening_a_win32_window.md renamed to book_src/opening_a_window/win32.md

Lines changed: 64 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,26 @@
11

22
# Opening a Win32 Window
33

4-
Alright, if we wanna draw a triangle, we have to have a window to draw the triangle in.
4+
On Windows, the C oriented API is called "Win32".
55

6-
Uh, how do we do that? For the sake of the lesson, let's imagine I don't know how to do that.
6+
There's also some C++ oriented APIs for interacting with Windows as well (called COM and WinRT).
7+
8+
It's *much* easier for Rust to bind to and interact with a C oriented API than a C++ oriented API,
9+
so we'll start with just using Win32 to interact with Windows.
710

811
## Search The Web
912

10-
Okay so we don't know what to do, let's ask the internet nicely.
13+
Okay, for the sake of the lesson let's pretend that *even I* don't know what to do.
14+
15+
Let's start by asking the internet nicely.
1116
Something like ["open a window win32"](https://duckduckgo.com/?q=open+a+window+win32) sounds right.
1217
Hey look, that [first result](https://docs.microsoft.com/en-us/windows/win32/learnwin32/creating-a-window) is straight from Microsoft.
1318
It's a whole little tutorial on how to open a window.
1419
Perfect, just what we wanted.
1520

1621
## Starting The Win32 Windowing Tutorial
1722

18-
Alright, let's read the first paragraph of the [windowing tutorial](https://docs.microsoft.com/en-us/windows/win32/learnwin32/creating-a-window)
23+
Let's read the first paragraph of the [windowing tutorial](https://docs.microsoft.com/en-us/windows/win32/learnwin32/creating-a-window)
1924
that we just found...
2025

2126
To summarize the opening portion:
@@ -470,7 +475,9 @@ depending on how you're building the C++ program,
470475
and also keeping in mind that we're always going to be using the `W` versions of things,
471476
then the equivalent Rust would be something like this:
472477
```rust
473-
let mut wc: WNDCLASSW = unsafe { core::mem::zeroed() };
478+
fn main () {
479+
let mut wc: WNDCLASSW = unsafe { core::mem::zeroed() };
480+
}
474481
```
475482
We haven't even called the OS and we've already got `unsafe` stuff going on.
476483

@@ -519,7 +526,9 @@ It's a simple convention, but it keeps it obvious that the macro can go wrong if
519526

520527
Now our rust can look like this:
521528
```rust
522-
let mut wc = WNDCLASSW::default();
529+
fn main() {
530+
let mut wc = WNDCLASSW::default();
531+
}
523532
```
524533
And that's so much nicer, at least to my eyes.
525534

@@ -602,6 +611,7 @@ We do this with an [external block](https://doc.rust-lang.org/reference/items/ex
602611

603612
An external block just declares the signature of a function, like this:
604613
```rust
614+
// EXAMPLE USAGE
605615
extern ABI {
606616
fn NAME1(args) -> output;
607617

@@ -622,6 +632,7 @@ But who tells the linker what to link with to find the external functions?
622632
Well, you can use a build script, or you can put it right on the extern block.
623633

624634
```rust
635+
// EXAMPLE USAGE
625636
#[link(name = "LibraryName")]
626637
extern ABI {
627638
fn NAME1(args) -> output;
@@ -874,23 +885,27 @@ Hey, look, the MSDN docs are using some of that extended typography we mentioned
874885

875886
Apparently we want our window creation to look something like this:
876887
```rust
877-
let sample_window_name_wn = wide_null("Sample Window Name");
878-
let hwnd = unsafe {
879-
CreateWindowExW(
880-
0,
881-
sample_window_class_wn.as_ptr(),
882-
sample_window_name_wn.as_ptr(),
883-
WS_OVERLAPPEDWINDOW,
884-
CW_USEDEFAULT,
885-
CW_USEDEFAULT,
886-
CW_USEDEFAULT,
887-
CW_USEDEFAULT,
888-
core::ptr::null_mut(),
889-
core::ptr::null_mut(),
890-
hInstance,
891-
core::ptr::null_mut(),
892-
)
893-
};
888+
fn main() {
889+
// first register the class, as before
890+
891+
let sample_window_name_wn = wide_null("Sample Window Name");
892+
let hwnd = unsafe {
893+
CreateWindowExW(
894+
0,
895+
sample_window_class_wn.as_ptr(),
896+
sample_window_name_wn.as_ptr(),
897+
WS_OVERLAPPEDWINDOW,
898+
CW_USEDEFAULT,
899+
CW_USEDEFAULT,
900+
CW_USEDEFAULT,
901+
CW_USEDEFAULT,
902+
core::ptr::null_mut(),
903+
core::ptr::null_mut(),
904+
hInstance,
905+
core::ptr::null_mut(),
906+
)
907+
};
908+
}
894909
```
895910

896911
Now we just have to define `WS_OVERLAPPEDWINDOW` and `CW_USEDEFAULT`.
@@ -955,19 +970,14 @@ We just did it to fill in a little bit so the compiler would be cool.
955970
Now that we're tying to turn on the program on for real (even for a second),
956971
we need a real window procedure.
957972
But we don't know how to write one yet.
958-
Never fear, there's a [DefWindowProcW](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-defwindowprocw)
959-
function that you can use to handle any messages you don't know how to handle.
973+
Never fear, there's a function called [DefWindowProcW](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-defwindowprocw).
974+
It's the "Default Window Procedure", that you can use to handle any messages you don't want to handle.
960975
Right now, for us, that's all of them.
961976

962977
```rust
963978
fn main() {
964-
let hInstance = unsafe { GetModuleHandleW(null()) };
965-
let sample_window_class_wn = wide_null("Sample Window Class");
966-
967-
let mut wc = WNDCLASSW::default();
979+
// ...
968980
wc.lpfnWndProc = Some(DefWindowProcW);
969-
wc.hInstance = hInstance;
970-
wc.lpszClassName = sample_window_class_wn.as_ptr();
971981
// ...
972982
}
973983

@@ -1041,14 +1051,18 @@ extern "system" {
10411051

10421052
We have to get them in a loop of course, because we'll be getting a whole lot of them.
10431053
```rust
1044-
let mut msg = MSG::default();
1045-
loop {
1046-
let message_return = unsafe { GetMessageW(&mut msg, null_mut(), 0, 0) };
1047-
if message_return == 0 {
1048-
break;
1049-
} else if message_return == -1 {
1050-
let last_error = unsafe { GetLastError() };
1051-
panic!("Error with `GetMessageW`, error code: {}", last_error);
1054+
fn main() {
1055+
// first open the window
1056+
1057+
let mut msg = MSG::default();
1058+
loop {
1059+
let message_return = unsafe { GetMessageW(&mut msg, null_mut(), 0, 0) };
1060+
if message_return == 0 {
1061+
break;
1062+
} else if message_return == -1 {
1063+
let last_error = unsafe { GetLastError() };
1064+
panic!("Error with `GetMessageW`, error code: {}", last_error);
1065+
}
10521066
}
10531067
}
10541068
```
@@ -1129,6 +1143,7 @@ pub unsafe extern "system" fn window_procedure(
11291143
```
11301144
One little problem here is that `DestroyWindow` and `PostQuitMessage` have different return types.
11311145
Even though we're ignoring the output of `DestroyWindow`, it's a type error to have it like this.
1146+
We can suppress the output of `DestroyWindow` by putting it in a block and having a `;` after it.
11321147

11331148
```rust
11341149
pub unsafe extern "system" fn window_procedure(
@@ -1144,7 +1159,7 @@ pub unsafe extern "system" fn window_procedure(
11441159
0
11451160
}
11461161
```
1147-
Ehhhhhh, I'm not sure if I'm a fan of rustfmt making it look like that.
1162+
Ehhhhhh, I'm not sure if I'm a fan of `rustfmt` making it look like that.
11481163

11491164
```rust
11501165
pub unsafe extern "system" fn window_procedure(
@@ -1160,7 +1175,7 @@ pub unsafe extern "system" fn window_procedure(
11601175
```
11611176
Oh, yeah, that's the good stuff.
11621177
We can use `drop` to throw away the `i32` value,
1163-
so we don't need the `;` and braces,
1178+
so then we don't need the `;` and braces,
11641179
so rustfmt keeps it on a single line.
11651180
I am *all about* that compact code stuff.
11661181

@@ -1180,7 +1195,11 @@ and then the default window procedure will set the cursor to be the right image
11801195

11811196
We're supposed to call it with something like:
11821197
```rust
1183-
wc.hCursor = unsafe { LoadCursorW(hInstance, IDC_ARROW) };
1198+
fn main() {
1199+
// ...
1200+
wc.hCursor = unsafe { LoadCursorW(hInstance, IDC_ARROW) };
1201+
// ...
1202+
}
11841203
```
11851204

11861205
And the extern function is easy to do:
@@ -1369,6 +1388,7 @@ const WM_CREATE: u32 = 0x0001;
13691388

13701389
And we check for them in our window procedure:
13711390
```rust
1391+
// in the window_procedure
13721392
match Msg {
13731393
WM_NCCREATE => {
13741394
println!("NC Create");
@@ -1400,6 +1420,7 @@ Okay, so far all of our messages have asked us to just *always* return 0 when th
14001420
and this is the first message we've been handling that we had to decide to return 0 or not.
14011421
Well, right now our window creation should always proceed, so here we go:
14021422
```rust
1423+
// in the window_procedure
14031424
WM_NCCREATE => {
14041425
println!("NC Create");
14051426
return 1;
@@ -1437,6 +1458,7 @@ Right, so, we have to have a void pointer to pass to the message.
14371458
Uh, just to pick something, let's pass our message a pointer to the number 5.
14381459

14391460
```rust
1461+
// in main
14401462
let lparam: *mut i32 = Box::leak(Box::new(5_i32));
14411463
let hwnd = unsafe {
14421464
CreateWindowExW(

book_src/win32_window_cleanup.md renamed to book_src/opening_a_window/win32_cleanup.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# Win32 Window Cleanup
22

3-
During the last article I said that we'd just write all our code into `main.rs`,
4-
and then we could sort it into a library later.
3+
During our introduction to Win32 I said that we'd just write all our code into `main.rs`,
4+
and then we could sort it into the library later.
5+
56
Well, later is now.
67

78
## New Files

0 commit comments

Comments
 (0)