1 /******************************************************************************
4 * modified: [ 03-08-15 ] Ge van Geldorp <ge@gse.nl>
6 * modified: [ 94-10-8 ] Ge van Geldorp <Ge.vanGeldorp@lr.tudelft.nl>
8 * modified: [ 3-7-93 ] Jamie Zawinski <jwz@lucid.com>
9 * added the XRoger logo, cleaned up resources, made
10 * grid size a parameter.
11 * modified: [ 3-3-93 ] Jim Randell <jmr@mddjmr.fc.hp.com>
12 * Added the colour stuff and integrated it with jwz's
13 * screenhack stuff. There's still some work that could
14 * be done on this, particularly allowing a resource to
15 * specify how big the squares are.
16 * modified: [ 10-4-88 ] Richard Hess ...!uunet!cimshop!rhess
17 * [ Revised primary execution loop within main()...
18 * [ Extended X event handler, check_events()...
19 * modified: [ 1-29-88 ] Dave Lemke lemke@sun.com
21 * [ Note the word "hacked" -- this is extremely ugly, but at
22 * [ least it does the job. NOT a good programming example
24 * original: [ 6/21/85 ] Martin Weiss Sun Microsystems [ SunView ]
26 ******************************************************************************
27 Copyright 1988 by Sun Microsystems, Inc. Mountain View, CA.
31 Permission to use, copy, modify, and distribute this software and its
32 documentation for any purpose and without fee is hereby granted,
33 provided that the above copyright notice appear in all copies and that
34 both that copyright notice and this permission notice appear in
35 supporting documentation, and that the names of Sun or MIT not be
36 used in advertising or publicity pertaining to distribution of the
37 software without specific prior written permission. Sun and M.I.T.
38 make no representations about the suitability of this software for
39 any purpose. It is provided "as is" without any express or implied warranty.
41 SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
42 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 PURPOSE. IN NO EVENT SHALL SUN BE LIABLE FOR ANY SPECIAL, INDIRECT
44 OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
45 OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
46 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
47 OR PERFORMANCE OF THIS SOFTWARE.
48 *****************************************************************************/
55 #include <windows.h> /* required for all Windows applications */
57 #if !defined (APIENTRY) /* Windows NT defines APIENTRY, but 3.x doesn't */
58 #define APIENTRY far pascal
61 #if !defined(WIN32) /* Windows 3.x uses a FARPROC for dialogs */
62 #define DLGPROC FARPROC
65 static BOOL
InitInstance(HINSTANCE hInstance
, HWND hParent
);
66 LRESULT CALLBACK
MazeWndProc(HWND hWnd
, UINT message
, WPARAM uParam
,
69 HINSTANCE hInst
; /* current instance */
70 HWND hWnd
; /* Main window handle.*/
78 WCHAR szAppName
[] = L
"Maze"; /* The name of this application */
79 WCHAR szTitle
[] = L
"Maze"; /* The title bar text */
81 static int solve_delay
, pre_solve_delay
, post_solve_delay
;
83 #define MAX_MAZE_SIZE_X ((unsigned long) 250)
84 #define MAX_MAZE_SIZE_Y ((unsigned long) 250)
86 #define MOVE_LIST_SIZE (MAX_MAZE_SIZE_X * MAX_MAZE_SIZE_Y)
88 #define WALL_TOP 0x8000
89 #define WALL_RIGHT 0x4000
90 #define WALL_BOTTOM 0x2000
91 #define WALL_LEFT 0x1000
93 #define DOOR_IN_TOP 0x800
94 #define DOOR_IN_RIGHT 0x400
95 #define DOOR_IN_BOTTOM 0x200
96 #define DOOR_IN_LEFT 0x100
97 #define DOOR_IN_ANY 0xF00
99 #define DOOR_OUT_TOP 0x80
100 #define DOOR_OUT_RIGHT 0x40
101 #define DOOR_OUT_BOTTOM 0x20
102 #define DOOR_OUT_LEFT 0x10
104 #define START_SQUARE 0x2
105 #define END_SQUARE 0x1
110 #define get_random(x) (rand() % (x))
112 static unsigned short maze
[MAX_MAZE_SIZE_X
][MAX_MAZE_SIZE_Y
];
119 } move_list
[MOVE_LIST_SIZE
], save_path
[MOVE_LIST_SIZE
], path
[MOVE_LIST_SIZE
];
121 static int maze_size_x
, maze_size_y
;
122 static long sqnum
, path_length
;
123 static int cur_sq_x
, cur_sq_y
;
124 static int start_x
, start_y
, start_dir
, end_x
, end_y
, end_dir
;
125 static int grid_width
, grid_height
;
127 static int state
= 1, pathi
= 0;
130 set_maze_sizes (width
, height
)
133 maze_size_x
= width
/ grid_width
;
134 maze_size_y
= height
/ grid_height
;
139 initialize_maze() /* draw the surrounding wall and start/end squares */
141 register int i
, j
, wall
;
143 /* initialize all squares */
144 for ( i
=0; i
<maze_size_x
; i
++) {
145 for ( j
=0; j
<maze_size_y
; j
++) {
151 for ( i
=0; i
<maze_size_x
; i
++ ) {
152 maze
[i
][0] |= WALL_TOP
;
156 for ( j
=0; j
<maze_size_y
; j
++ ) {
157 maze
[maze_size_x
-1][j
] |= WALL_RIGHT
;
161 for ( i
=0; i
<maze_size_x
; i
++ ) {
162 maze
[i
][maze_size_y
-1] |= WALL_BOTTOM
;
166 for ( j
=0; j
<maze_size_y
; j
++ ) {
167 maze
[0][j
] |= WALL_LEFT
;
170 /* set start square */
171 wall
= get_random(4);
174 i
= get_random(maze_size_x
);
179 j
= get_random(maze_size_y
);
182 i
= get_random(maze_size_x
);
187 j
= get_random(maze_size_y
);
190 maze
[i
][j
] |= START_SQUARE
;
191 maze
[i
][j
] |= ( DOOR_IN_TOP
>> wall
);
192 maze
[i
][j
] &= ~( WALL_TOP
>> wall
);
204 i
= get_random(maze_size_x
);
209 j
= get_random(maze_size_y
);
212 i
= get_random(maze_size_x
);
217 j
= get_random(maze_size_y
);
220 maze
[i
][j
] |= END_SQUARE
;
221 maze
[i
][j
] |= ( DOOR_OUT_TOP
>> wall
);
222 maze
[i
][j
] &= ~( WALL_TOP
>> wall
);
228 static int choose_door ();
229 static long backup ();
230 static void draw_wall ();
231 static void draw_solid_square(int, int, int, HDC
, HBRUSH
);
232 static void enter_square(int, HDC
, HBRUSH
);
235 create_maze() /* create a maze layout given the intiialized maze */
237 register int i
, newdoor
= 0;
242 move_list
[sqnum
].x
= cur_sq_x
;
243 move_list
[sqnum
].y
= cur_sq_y
;
244 move_list
[sqnum
].dir
= newdoor
;
245 while ( ( newdoor
= choose_door(hDC
) ) == -1 ) { /* pick a door */
246 if ( backup() == -1 ) { /* no more doors ... backup */
247 ReleaseDC(hWnd
, hDC
);
248 return; /* done ... return */
252 /* mark the out door */
253 maze
[cur_sq_x
][cur_sq_y
] |= ( DOOR_OUT_TOP
>> newdoor
);
267 /* mark the in door */
268 maze
[cur_sq_x
][cur_sq_y
] |= ( DOOR_IN_TOP
>> ((newdoor
+2)%4) );
270 /* if end square set path length and save path */
271 if ( maze
[cur_sq_x
][cur_sq_y
] & END_SQUARE
) {
273 for ( i
=0; i
<path_length
; i
++) {
274 save_path
[i
].x
= move_list
[i
].x
;
275 save_path
[i
].y
= move_list
[i
].y
;
276 save_path
[i
].dir
= move_list
[i
].dir
;
286 choose_door(HDC hDC
) /* pick a new path */
289 register int num_candidates
;
294 if ( maze
[cur_sq_x
][cur_sq_y
] & DOOR_IN_TOP
)
296 if ( maze
[cur_sq_x
][cur_sq_y
] & DOOR_OUT_TOP
)
298 if ( maze
[cur_sq_x
][cur_sq_y
] & WALL_TOP
)
300 if ( maze
[cur_sq_x
][cur_sq_y
- 1] & DOOR_IN_ANY
) {
301 maze
[cur_sq_x
][cur_sq_y
] |= WALL_TOP
;
302 maze
[cur_sq_x
][cur_sq_y
- 1] |= WALL_BOTTOM
;
303 draw_wall(cur_sq_x
, cur_sq_y
, 0, hDC
);
306 candidates
[num_candidates
++] = 0;
310 if ( maze
[cur_sq_x
][cur_sq_y
] & DOOR_IN_RIGHT
)
312 if ( maze
[cur_sq_x
][cur_sq_y
] & DOOR_OUT_RIGHT
)
314 if ( maze
[cur_sq_x
][cur_sq_y
] & WALL_RIGHT
)
316 if ( maze
[cur_sq_x
+ 1][cur_sq_y
] & DOOR_IN_ANY
) {
317 maze
[cur_sq_x
][cur_sq_y
] |= WALL_RIGHT
;
318 maze
[cur_sq_x
+ 1][cur_sq_y
] |= WALL_LEFT
;
319 draw_wall(cur_sq_x
, cur_sq_y
, 1, hDC
);
322 candidates
[num_candidates
++] = 1;
326 if ( maze
[cur_sq_x
][cur_sq_y
] & DOOR_IN_BOTTOM
)
328 if ( maze
[cur_sq_x
][cur_sq_y
] & DOOR_OUT_BOTTOM
)
330 if ( maze
[cur_sq_x
][cur_sq_y
] & WALL_BOTTOM
)
332 if ( maze
[cur_sq_x
][cur_sq_y
+ 1] & DOOR_IN_ANY
) {
333 maze
[cur_sq_x
][cur_sq_y
] |= WALL_BOTTOM
;
334 maze
[cur_sq_x
][cur_sq_y
+ 1] |= WALL_TOP
;
335 draw_wall(cur_sq_x
, cur_sq_y
, 2, hDC
);
338 candidates
[num_candidates
++] = 2;
342 if ( maze
[cur_sq_x
][cur_sq_y
] & DOOR_IN_LEFT
)
344 if ( maze
[cur_sq_x
][cur_sq_y
] & DOOR_OUT_LEFT
)
346 if ( maze
[cur_sq_x
][cur_sq_y
] & WALL_LEFT
)
348 if ( maze
[cur_sq_x
- 1][cur_sq_y
] & DOOR_IN_ANY
) {
349 maze
[cur_sq_x
][cur_sq_y
] |= WALL_LEFT
;
350 maze
[cur_sq_x
- 1][cur_sq_y
] |= WALL_RIGHT
;
351 draw_wall(cur_sq_x
, cur_sq_y
, 3, hDC
);
354 candidates
[num_candidates
++] = 3;
357 if (num_candidates
== 0)
359 if (num_candidates
== 1)
360 return ( candidates
[0] );
361 return ( candidates
[ get_random(num_candidates
) ] );
367 backup() /* back up a move */
371 cur_sq_x
= move_list
[sqnum
].x
;
372 cur_sq_y
= move_list
[sqnum
].y
;
380 draw_solid_square(i
, j
, dir
, hDC
, hBrush
) /* draw a solid square in a square */
381 register int i
, j
, dir
;
389 rc
.left
= border_x
+ bw
+ grid_width
* i
;
390 rc
.right
= rc
.left
+ grid_width
- (bw
+ bw
);
391 rc
.top
= border_y
- bw
+ grid_height
* j
;
392 rc
.bottom
= rc
.top
+ grid_height
;
395 rc
.left
= border_x
+ bw
+ grid_width
* i
;
396 rc
.right
= rc
.left
+ grid_width
;
397 rc
.top
= border_y
+ bw
+ grid_height
* j
;
398 rc
.bottom
= rc
.top
+ grid_height
- (bw
+ bw
);
401 rc
.left
= border_x
+ bw
+ grid_width
* i
;
402 rc
.right
= rc
.left
+ grid_width
- (bw
+ bw
);
403 rc
.top
= border_y
+ bw
+ grid_height
* j
;
404 rc
.bottom
= rc
.top
+ grid_height
;
407 rc
.left
= border_x
- bw
+ grid_width
* i
;
408 rc
.right
= rc
.left
+ grid_width
;
409 rc
.top
= border_y
+ bw
+ grid_height
* j
;
410 rc
.bottom
= rc
.top
+ grid_height
- (bw
+ bw
);
413 (void) FillRect(hDC
, &rc
, hBrush
);
417 draw_maze_border(HWND hWnd
, HDC hDC
) /* draw the maze outline */
422 SelectObject(hDC
, hPenWall
);
424 for ( i
=0; i
<maze_size_x
; i
++) {
425 if ( maze
[i
][0] & WALL_TOP
) {
426 MoveToEx(hDC
, border_x
+ grid_width
* i
, border_y
, NULL
);
427 (void) LineTo(hDC
, border_x
+ grid_width
* (i
+ 1) - 1, border_y
);
429 if ((maze
[i
][maze_size_y
- 1] & WALL_BOTTOM
)) {
430 MoveToEx(hDC
, border_x
+ grid_width
* i
,
431 border_y
+ grid_height
* (maze_size_y
) - 1, NULL
);
432 (void) LineTo(hDC
, border_x
+ grid_width
* (i
+1) - 1,
433 border_y
+ grid_height
* (maze_size_y
) - 1);
436 for ( j
=0; j
<maze_size_y
; j
++) {
437 if ( maze
[maze_size_x
- 1][j
] & WALL_RIGHT
) {
438 MoveToEx(hDC
, border_x
+ grid_width
* maze_size_x
- 1,
439 border_y
+ grid_height
* j
, NULL
);
440 (void) LineTo(hDC
, border_x
+ grid_width
* maze_size_x
- 1,
441 border_y
+ grid_height
* (j
+1) - 1);
443 if ( maze
[0][j
] & WALL_LEFT
) {
444 MoveToEx(hDC
, border_x
, border_y
+ grid_height
* j
, NULL
);
445 (void) LineTo(hDC
, border_x
, border_y
+ grid_height
* (j
+1) - 1);
449 hBrush
= GetStockObject(WHITE_BRUSH
); // FIXME: do not hardcode
450 draw_solid_square (start_x
, start_y
, start_dir
, hDC
, hBrush
);
451 draw_solid_square (end_x
, end_y
, end_dir
, hDC
, hBrush
);
456 draw_wall(i
, j
, dir
, hDC
) /* draw a single wall */
460 SelectObject(hDC
, hPenWall
);
464 MoveToEx(hDC
, border_x
+ grid_width
* i
, border_y
+ grid_height
* j
, NULL
);
465 (void) LineTo(hDC
, border_x
+ grid_width
* (i
+1),
466 border_y
+ grid_height
* j
);
469 MoveToEx(hDC
, border_x
+ grid_width
* (i
+1), border_y
+ grid_height
* j
,
471 (void) LineTo(hDC
, border_x
+ grid_width
* (i
+1),
472 border_y
+ grid_height
* (j
+1));
475 MoveToEx(hDC
, border_x
+ grid_width
* i
, border_y
+ grid_height
* (j
+1),
477 (void) LineTo(hDC
, border_x
+ grid_width
* (i
+1),
478 border_y
+ grid_height
* (j
+1));
481 MoveToEx(hDC
, border_x
+ grid_width
* i
, border_y
+ grid_height
* j
,
483 (void) LineTo(hDC
, border_x
+ grid_width
* i
,
484 border_y
+ grid_height
* (j
+1));
490 begin_solve_maze() /* solve it with graphical feedback */
492 static long grayPattern
[] = {
502 static RGBQUAD argbq
[] = {
509 pbmi
= malloc(sizeof(BITMAPINFOHEADER
) + sizeof(argbq
) + sizeof(grayPattern
));
510 pbmi
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
511 pbmi
->bmiHeader
.biWidth
= 8;
512 pbmi
->bmiHeader
.biHeight
= 8;
513 pbmi
->bmiHeader
.biPlanes
= 1;
514 pbmi
->bmiHeader
.biBitCount
= 1;
515 pbmi
->bmiHeader
.biCompression
= BI_RGB
;
516 (void) memcpy(pbmi
->bmiColors
, argbq
, sizeof(argbq
));
517 (void) memcpy(pbmi
->bmiColors
+ 2, grayPattern
, sizeof(grayPattern
));
519 /* FIXME Pattern brushes not yet implemented in ReactOS */
520 hBrushDead
= CreateDIBPatternBrushPt(pbmi
, DIB_RGB_COLORS
);
522 hBrushDead
= CreateSolidBrush(RGB(255, 0, 0));
524 // hBrushDead = CreateHatchBrush(HS_DIAGCROSS, RGB(255, 0, 0));
526 hBrushLiving
= CreateSolidBrush(RGB(0, 255, 0));
528 /* plug up the surrounding wall */
529 maze
[start_x
][start_y
] |= (WALL_TOP
>> start_dir
);
530 maze
[end_x
][end_y
] |= (WALL_TOP
>> end_dir
);
532 /* initialize search path */
534 path
[pathi
].x
= end_x
;
535 path
[pathi
].y
= end_y
;
536 path
[pathi
].dir
= -1;
540 solve_maze() /* solve it with graphical feedback */
547 if ( ++path
[pathi
].dir
>= 4 ) {
549 draw_solid_square( (int)(path
[pathi
].x
), (int)(path
[pathi
].y
),
550 (int)(path
[pathi
].dir
), hDC
, hBrushDead
);
553 else if ( ! (maze
[path
[pathi
].x
][path
[pathi
].y
] &
554 (WALL_TOP
>> path
[pathi
].dir
)) &&
555 ( (pathi
== 0) || ( (path
[pathi
].dir
!=
556 (int)(path
[pathi
-1].dir
+2)%4) ) ) ) {
557 enter_square(pathi
, hDC
, hBrushLiving
);
559 if ( maze
[path
[pathi
].x
][path
[pathi
].y
] & START_SQUARE
) {
560 DeleteObject(hBrushLiving
);
561 DeleteObject(hBrushDead
);
562 ReleaseDC(hWnd
, hDC
);
570 } while (! action_done
);
577 enter_square(int n
, HDC hDC
, HBRUSH hBrush
) /* move into a neighboring square */
579 draw_solid_square( (int)path
[n
].x
, (int)path
[n
].y
,
580 (int)path
[n
].dir
, hDC
, hBrush
);
583 switch (path
[n
].dir
) {
584 case 0: path
[n
+1].x
= path
[n
].x
;
585 path
[n
+1].y
= path
[n
].y
- 1;
587 case 1: path
[n
+1].x
= path
[n
].x
+ 1;
588 path
[n
+1].y
= path
[n
].y
;
590 case 2: path
[n
+1].x
= path
[n
].x
;
591 path
[n
+1].y
= path
[n
].y
+ 1;
593 case 3: path
[n
+1].x
= path
[n
].x
- 1;
594 path
[n
+1].y
= path
[n
].y
;
600 start_timer(HWND hWnd
, int iTimeout
)
603 SetTimer(hWnd
, 1, iTimeout
, NULL
);
606 /****************************************************************************
608 FUNCTION: WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
610 PURPOSE: calls initialization function, processes message loop
614 Windows recognizes this function by name as the initial entry point
615 for the program. This function calls the application initialization
616 routine, if no other instance of the program is running, and always
617 calls the instance initialization routine. It then executes a message
618 retrieval and dispatch loop that is the top-level control structure
619 for the remainder of execution. The loop is terminated when a WM_QUIT
620 message is received, at which time this function exits the application
621 instance by returning the value passed by PostQuitMessage().
623 If this function must abort before entering the message loop, it
624 returns the conventional value NULL.
626 ****************************************************************************/
628 int APIENTRY
MazeMain(
630 HINSTANCE hPrevInstance
,
637 /* Perform initializations that apply to a specific instance */
639 if (!InitInstance(hInstance
, hParent
)) {
646 /* Acquire and dispatch messages until a WM_QUIT message is received. */
650 (void) WaitMessage();
652 while (0 != state
&& PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
)) {
653 if (WM_QUIT
== msg
.message
) {
656 DispatchMessage(&msg
); /* Dispatches message to window */
666 SendMessage(hWnd
, WM_ERASEBKGND
, (WPARAM
) hDC
, (LPARAM
) 0);
667 draw_maze_border(hWnd
, hDC
);
668 ReleaseDC(hWnd
, hDC
);
676 start_timer(hWnd
, pre_solve_delay
);
686 if (0 != solve_delay
) {
687 start_timer(hWnd
, solve_delay
);
699 if (! solve_maze()) {
700 if (0 != solve_delay
) {
701 start_timer(hWnd
, solve_delay
);
709 start_timer(hWnd
, post_solve_delay
);
723 return (msg
.wParam
); /* Returns the value from PostQuitMessage */
727 /****************************************************************************
729 FUNCTION: InitInstance(HINSTANCE, int)
731 PURPOSE: Saves instance handle and creates main window
735 This function is called at initialization time for every instance of
736 this application. This function performs initialization tasks that
737 cannot be shared by multiple instances.
739 In this case, we save the instance handle in a static variable and
740 create and display the main program window.
742 ****************************************************************************/
744 static BOOL
InitInstance(
750 /* Save the instance handle in static variable, which will be used in
751 many subsequence calls from this application to Windows. */
753 hInst
= hInstance
; /* Store instance handle in our global variable */
755 GetClientRect(hParent
, &rect
);
757 /* Create a main window for this application instance. */
759 szAppName
, /* See RegisterClass() call. */
760 szTitle
, /* Text for window title bar. */
761 WS_CHILD
,/* Window style. */
762 0, 0, rect
.right
/2, rect
.bottom
/2, /* Use default positioning */
763 hParent
, /* We use a Parent. */
764 NULL
, /* Use the window class menu. */
765 hInstance
, /* This instance owns this window. */
766 NULL
/* We don't use any data in our WM_CREATE */
770 // If window could not be created, return "failure"
775 // Make the window visible; update its client area; and return "success"
776 ShowWindow(hWnd
, SW_SHOW
); // Show the window
778 UpdateWindow(hWnd
); // Sends WM_PAINT message
780 hPenWall
= CreatePen(PS_SOLID
, 3, RGB(150,150,150));
782 return (TRUE
); // We succeeded...
787 OnCreate(HWND hWnd
, LPCREATESTRUCT lpCreateStruct
)
792 srand((unsigned) time(NULL
));
795 /* FIXME GetPrivateProfileInt not yet implemented in ReactOS */
796 size
= GetPrivateProfileInt("maze", "gridsize", 0, "maze.ini");
797 pre_solve_delay
= GetPrivateProfileInt("maze", "predelay", 5000,
799 post_solve_delay
= GetPrivateProfileInt("maze", "postdelay", 5000,
801 solve_delay
= GetPrivateProfileInt("maze", "solvedelay", 10,
805 pre_solve_delay
= 5000;
806 post_solve_delay
= 5000;
811 size
= 7 + (rand() % 30);
813 grid_width
= grid_height
= size
;
814 bw
= (size
> 6 ? 3 : (size
-1)/2);
816 GetClientRect(hWnd
, &rc
);
817 set_maze_sizes(rc
.right
- rc
.left
, rc
.bottom
- rc
.top
);
822 void OnTimer(HWND hwnd
, UINT id
)
827 /****************************************************************************
829 FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
831 PURPOSE: Processes messages
835 WM_DESTROY - destroy window
839 ****************************************************************************/
841 LRESULT CALLBACK
MazeWndProc(
842 HWND hWnd
, // window handle
843 UINT message
, // type of message
844 WPARAM wParam
, // additional information
845 LPARAM lParam
) // additional information
851 OnCreate(hWnd
, (LPCREATESTRUCT
) lParam
);
854 BeginPaint(hWnd
, &ps
);
858 OnTimer(hWnd
, wParam
);
860 case WM_DESTROY
: // message: window being destroyed
864 default: // Passes it on if unproccessed
865 return (DefWindowProc(hWnd
, message
, wParam
, lParam
));