main.c 31.1 KB
Newer Older
Joshua Thielen's avatar
Joshua Thielen committed
1 2
/*
 * WineMine (main.c)
3
 *
4
 * Copyright 2000 Joshua Thielen
5 6 7 8 9 10 11 12 13 14 15 16 17
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
Joshua Thielen's avatar
Joshua Thielen committed
19 20
 */

21 22
#define WIN32_LEAN_AND_MEAN

Joshua Thielen's avatar
Joshua Thielen committed
23 24 25
#include <string.h>
#include <time.h>
#include <windows.h>
26
#include <stdlib.h>
27
#include <shellapi.h>
Joshua Thielen's avatar
Joshua Thielen committed
28 29 30
#include "main.h"
#include "resource.h"

31 32 33
#include <wine/debug.h>

WINE_DEFAULT_DEBUG_CHANNEL(winemine);
Joshua Thielen's avatar
Joshua Thielen committed
34

35
static const DWORD wnd_style = WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX;
36 37 38 39 40 41 42 43 44 45 46 47 48
static const WCHAR registry_key[] = {'S','o','f','t','w','a','r','e','\\',
                                     'M','i','c','r','o','s','o','f','t','\\',
                                     'W','i','n','M','i','n','e',0};

static const WCHAR xposW[] = {'X','p','o','s',0};
static const WCHAR yposW[] = {'Y','p','o','s',0};
static const WCHAR heightW[] = {'H','e','i','g','h','t',0};
static const WCHAR widthW[] = {'W','i','d','t','h',0};
static const WCHAR minesW[] = {'M','i','n','e','s',0};
static const WCHAR difficultyW[] = {'D','i','f','f','i','c','u','l','t','y',0};
static const WCHAR markW[] = {'M','a','r','k',0};
static const WCHAR nameW[] = {'N','a','m','e','%','u',0};
static const WCHAR timeW[] = {'T','i','m','e','%','u',0};
49

50
void CheckLevel( BOARD *p_board )
Joshua Thielen's avatar
Joshua Thielen committed
51
{
52 53
    if( p_board->rows < BEGINNER_ROWS )
        p_board->rows = BEGINNER_ROWS;
Joshua Thielen's avatar
Joshua Thielen committed
54

55 56
    if( p_board->rows > MAX_ROWS )
        p_board->rows = MAX_ROWS;
Joshua Thielen's avatar
Joshua Thielen committed
57

58 59
    if( p_board->cols < BEGINNER_COLS )
        p_board->cols = BEGINNER_COLS;
Joshua Thielen's avatar
Joshua Thielen committed
60

61 62
    if( p_board->cols > MAX_COLS )
        p_board->cols = MAX_COLS;
63

64 65
    if( p_board->mines < BEGINNER_MINES )
        p_board->mines = BEGINNER_MINES;
66

67 68
    if( p_board->mines > ( p_board->cols - 1 ) * ( p_board->rows - 1 ) )
        p_board->mines = ( p_board->cols - 1 ) * ( p_board->rows - 1 );
Joshua Thielen's avatar
Joshua Thielen committed
69 70
}

71
static void LoadBoard( BOARD *p_board )
Joshua Thielen's avatar
Joshua Thielen committed
72 73 74 75
{
    DWORD size;
    DWORD type;
    HKEY hkey;
76 77
    WCHAR data[MAX_PLAYER_NAME_SIZE+1];
    WCHAR key_name[8];
Joshua Thielen's avatar
Joshua Thielen committed
78 79
    unsigned i;

80
    RegOpenKeyExW( HKEY_CURRENT_USER, registry_key, 0, KEY_QUERY_VALUE, &hkey );
81

82
    size = sizeof( p_board->pos.x );
83
    if( !RegQueryValueExW( hkey, xposW, NULL, &type,
84
            (LPBYTE) &p_board->pos.x, &size ) == ERROR_SUCCESS )
85
	p_board->pos.x = 0;
Joshua Thielen's avatar
Joshua Thielen committed
86

87
    size = sizeof( p_board->pos.y );
88
    if( !RegQueryValueExW( hkey, yposW, NULL, &type,
89
            (LPBYTE) &p_board->pos.y, &size ) == ERROR_SUCCESS )
90
        p_board->pos.y = 0;
Joshua Thielen's avatar
Joshua Thielen committed
91

92
    size = sizeof( p_board->rows );
93
    if( !RegQueryValueExW( hkey, heightW, NULL, &type,
94
            (LPBYTE) &p_board->rows, &size ) == ERROR_SUCCESS )
Joshua Thielen's avatar
Joshua Thielen committed
95 96
        p_board->rows = BEGINNER_ROWS;

97
    size = sizeof( p_board->cols );
98
    if( !RegQueryValueExW( hkey, widthW, NULL, &type,
99
            (LPBYTE) &p_board->cols, &size ) == ERROR_SUCCESS )
100 101
        p_board->cols = BEGINNER_COLS;

102
    size = sizeof( p_board->mines );
103
    if( !RegQueryValueExW( hkey, minesW, NULL, &type,
104
            (LPBYTE) &p_board->mines, &size ) == ERROR_SUCCESS )
105
        p_board->mines = BEGINNER_MINES;
Joshua Thielen's avatar
Joshua Thielen committed
106

107
    size = sizeof( p_board->difficulty );
108
    if( !RegQueryValueExW( hkey, difficultyW, NULL, &type,
109
            (LPBYTE) &p_board->difficulty, &size ) == ERROR_SUCCESS )
Joshua Thielen's avatar
Joshua Thielen committed
110 111
        p_board->difficulty = BEGINNER;

112
    size = sizeof( p_board->IsMarkQ );
113
    if( !RegQueryValueExW( hkey, markW, NULL, &type,
114
            (LPBYTE) &p_board->IsMarkQ, &size ) == ERROR_SUCCESS )
Joshua Thielen's avatar
Joshua Thielen committed
115
        p_board->IsMarkQ = TRUE;
116

Joshua Thielen's avatar
Joshua Thielen committed
117
    for( i = 0; i < 3; i++ ) {
118
        wsprintfW( key_name, nameW, i+1 );
Joshua Thielen's avatar
Joshua Thielen committed
119
        size = sizeof( data );
120
        if( RegQueryValueExW( hkey, key_name, NULL, &type,
121
                (LPBYTE) data, &size ) == ERROR_SUCCESS )
122
            lstrcpynW( p_board->best_name[i], data, sizeof(p_board->best_name[i])/sizeof(WCHAR) );
123
        else
124
            LoadStringW( p_board->hInst, IDS_NOBODY, p_board->best_name[i], MAX_PLAYER_NAME_SIZE+1 );
Joshua Thielen's avatar
Joshua Thielen committed
125
    }
126

Joshua Thielen's avatar
Joshua Thielen committed
127
    for( i = 0; i < 3; i++ ) {
128
        wsprintfW( key_name, timeW, i+1 );
129
        size = sizeof( p_board->best_time[i] );
130
        if( !RegQueryValueExW( hkey, key_name, NULL, &type,
131
                (LPBYTE) &p_board->best_time[i], &size ) == ERROR_SUCCESS )
Joshua Thielen's avatar
Joshua Thielen committed
132 133 134 135 136
            p_board->best_time[i] = 999;
    }
    RegCloseKey( hkey );
}

137
static void InitBoard( BOARD *p_board )
Joshua Thielen's avatar
Joshua Thielen committed
138
{
139
    HMENU hMenu;
140

141 142 143
    p_board->hMinesBMP = LoadBitmapW( p_board->hInst, MAKEINTRESOURCEW(IDI_MINES));
    p_board->hFacesBMP = LoadBitmapW( p_board->hInst, MAKEINTRESOURCEW(IDI_FACES));
    p_board->hLedsBMP = LoadBitmapW( p_board->hInst, MAKEINTRESOURCEW(IDI_LEDS));
144 145 146 147 148 149 150 151 152 153 154 155 156

    LoadBoard( p_board );

    hMenu = GetMenu( p_board->hWnd );
    CheckMenuItem( hMenu, IDM_BEGINNER + (unsigned) p_board->difficulty,
            MF_CHECKED );
    if( p_board->IsMarkQ )
        CheckMenuItem( hMenu, IDM_MARKQ, MF_CHECKED );
    else
        CheckMenuItem( hMenu, IDM_MARKQ, MF_UNCHECKED );
    CheckLevel( p_board );
}

157
static void SaveBoard( BOARD *p_board )
158 159 160
{
    HKEY hkey;
    unsigned i;
161 162
    WCHAR data[MAX_PLAYER_NAME_SIZE+1];
    WCHAR key_name[8];
163

164
    if( RegCreateKeyExW( HKEY_CURRENT_USER, registry_key,
165 166 167 168
	        0, NULL,
                REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
                &hkey, NULL ) != ERROR_SUCCESS)
        return;
169

170 171 172 173 174 175 176
    RegSetValueExW( hkey, xposW, 0, REG_DWORD, (LPBYTE) &p_board->pos.x, sizeof(p_board->pos.x) );
    RegSetValueExW( hkey, yposW, 0, REG_DWORD, (LPBYTE) &p_board->pos.y, sizeof(p_board->pos.y) );
    RegSetValueExW( hkey, difficultyW, 0, REG_DWORD, (LPBYTE) &p_board->difficulty, sizeof(p_board->difficulty) );
    RegSetValueExW( hkey, heightW, 0, REG_DWORD, (LPBYTE) &p_board->rows, sizeof(p_board->rows) );
    RegSetValueExW( hkey, widthW, 0, REG_DWORD, (LPBYTE) &p_board->cols, sizeof(p_board->cols) );
    RegSetValueExW( hkey, minesW, 0, REG_DWORD, (LPBYTE) &p_board->mines, sizeof(p_board->mines) );
    RegSetValueExW( hkey, markW, 0, REG_DWORD, (LPBYTE) &p_board->IsMarkQ, sizeof(p_board->IsMarkQ) );
Joshua Thielen's avatar
Joshua Thielen committed
177 178

    for( i = 0; i < 3; i++ ) {
179 180 181
        wsprintfW( key_name, nameW, i+1 );
        lstrcpynW( data, p_board->best_name[i], sizeof(data)/sizeof(WCHAR) );
        RegSetValueExW( hkey, key_name, 0, REG_SZ, (LPBYTE) data, (lstrlenW(data)+1) * sizeof(WCHAR) );
Joshua Thielen's avatar
Joshua Thielen committed
182 183 184
    }

    for( i = 0; i < 3; i++ ) {
185 186
        wsprintfW( key_name, timeW, i+1 );
        RegSetValueExW( hkey, key_name, 0, REG_DWORD, (LPBYTE) &p_board->best_time[i], sizeof(p_board->best_time[i]) );
Joshua Thielen's avatar
Joshua Thielen committed
187 188 189 190
    }
    RegCloseKey( hkey );
}

191
static void DestroyBoard( BOARD *p_board )
192 193 194 195 196 197
{
    DeleteObject( p_board->hFacesBMP );
    DeleteObject( p_board->hLedsBMP );
    DeleteObject( p_board->hMinesBMP );
}

198
static void SetDifficulty( BOARD *p_board, DIFFICULTY difficulty )
Joshua Thielen's avatar
Joshua Thielen committed
199
{
200 201 202
    HMENU hMenu;

    if ( difficulty == CUSTOM )
203
        if (DialogBoxParamW( p_board->hInst, MAKEINTRESOURCEW(DLG_CUSTOM), p_board->hWnd,
204 205
                    CustomDlgProc, (LPARAM) p_board) != 0)
           return;
Joshua Thielen's avatar
Joshua Thielen committed
206

207
    hMenu = GetMenu( p_board->hWnd );
Joshua Thielen's avatar
Joshua Thielen committed
208
    CheckMenuItem( hMenu, IDM_BEGINNER + p_board->difficulty, MF_UNCHECKED );
209
    p_board->difficulty = difficulty;
Joshua Thielen's avatar
Joshua Thielen committed
210
    CheckMenuItem( hMenu, IDM_BEGINNER + difficulty, MF_CHECKED );
211

Joshua Thielen's avatar
Joshua Thielen committed
212
    switch( difficulty ) {
213
    case BEGINNER:
Joshua Thielen's avatar
Joshua Thielen committed
214 215 216 217 218
        p_board->cols = BEGINNER_COLS;
        p_board->rows = BEGINNER_ROWS;
        p_board->mines = BEGINNER_MINES;
        break;

219
    case ADVANCED:
Joshua Thielen's avatar
Joshua Thielen committed
220 221 222 223 224 225 226 227
        p_board->cols = ADVANCED_COLS;
        p_board->rows = ADVANCED_ROWS;
        p_board->mines = ADVANCED_MINES;
        break;

    case EXPERT:
        p_board->cols = EXPERT_COLS;
        p_board->rows = EXPERT_ROWS;
228

229 230
        p_board->mines = EXPERT_MINES;
        break;
Joshua Thielen's avatar
Joshua Thielen committed
231 232

    case CUSTOM:
233
        break;
Joshua Thielen's avatar
Joshua Thielen committed
234 235 236
    }
}

237
static void ShiftBetween(LONG* x, LONG* y, LONG a, LONG b)
238 239 240 241 242 243 244 245 246 247
{
    if (*x < a) {
	*y += a - *x;
	*x = a;
    }
    else if (*y > b) {
	*x -= *y - b;
	*y = b;
    }
}
248 249

static void MoveOnScreen(RECT* rect)
250 251 252 253 254 255 256 257 258
{
    HMONITOR hMonitor;
    MONITORINFO mi;

    /* find the nearest monitor ... */
    hMonitor = MonitorFromRect(rect, MONITOR_DEFAULTTONEAREST);

    /* ... and move it into the work area (ie excluding task bar)*/
    mi.cbSize = sizeof(mi);
259
    GetMonitorInfoW(hMonitor, &mi);
260 261 262 263 264

    ShiftBetween(&rect->left, &rect->right, mi.rcWork.left, mi.rcWork.right);
    ShiftBetween(&rect->top, &rect->bottom, mi.rcWork.top, mi.rcWork.bottom);
}

265
static void CreateBoard( BOARD *p_board )
Joshua Thielen's avatar
Joshua Thielen committed
266
{
267
    int left, top, bottom, right;
268
    unsigned col, row;
269
    RECT wnd_rect;
Joshua Thielen's avatar
Joshua Thielen committed
270 271 272 273

    p_board->mb = MB_NONE;
    p_board->boxes_left = p_board->cols * p_board->rows - p_board->mines;
    p_board->num_flags = 0;
274

275 276 277 278 279 280 281 282 283 284 285
    /* Create the boxes...
     * We actually create them with an empty border,
     * so special care doesn't have to be taken on the edges
     */
    for( col = 0; col <= p_board->cols + 1; col++ )
      for( row = 0; row <= p_board->rows + 1; row++ ) {
        p_board->box[col][row].IsPressed = FALSE;
        p_board->box[col][row].IsMine = FALSE;
        p_board->box[col][row].FlagType = NORMAL;
        p_board->box[col][row].NumMines = 0;
      }
Joshua Thielen's avatar
Joshua Thielen committed
286 287

    p_board->width = p_board->cols * MINE_WIDTH + BOARD_WMARGIN * 2;
288 289

    p_board->height = p_board->rows * MINE_HEIGHT + LED_HEIGHT
Joshua Thielen's avatar
Joshua Thielen committed
290 291
        + BOARD_HMARGIN * 3;

292 293 294
    /* setting the mines rectangle boundary */
    left = BOARD_WMARGIN;
    top = BOARD_HMARGIN * 2 + LED_HEIGHT;
Joshua Thielen's avatar
Joshua Thielen committed
295 296 297 298
    right = left + p_board->cols * MINE_WIDTH;
    bottom = top + p_board->rows * MINE_HEIGHT;
    SetRect( &p_board->mines_rect, left, top, right, bottom );

299
    /* setting the face rectangle boundary */
Joshua Thielen's avatar
Joshua Thielen committed
300 301 302
    left = p_board->width / 2 - FACE_WIDTH / 2;
    top = BOARD_HMARGIN;
    right = left + FACE_WIDTH;
303
    bottom = top + FACE_HEIGHT;
Joshua Thielen's avatar
Joshua Thielen committed
304
    SetRect( &p_board->face_rect, left, top, right, bottom );
305 306

    /* setting the timer rectangle boundary */
Joshua Thielen's avatar
Joshua Thielen committed
307 308 309
    left = BOARD_WMARGIN;
    top = BOARD_HMARGIN;
    right = left + LED_WIDTH * 3;
310
    bottom = top + LED_HEIGHT;
Joshua Thielen's avatar
Joshua Thielen committed
311
    SetRect( &p_board->timer_rect, left, top, right, bottom );
312 313

    /* setting the counter rectangle boundary */
Joshua Thielen's avatar
Joshua Thielen committed
314 315 316
    left =  p_board->width - BOARD_WMARGIN - LED_WIDTH * 3;
    top = BOARD_HMARGIN;
    right = p_board->width - BOARD_WMARGIN;
317
    bottom = top + LED_HEIGHT;
Joshua Thielen's avatar
Joshua Thielen committed
318
    SetRect( &p_board->counter_rect, left, top, right, bottom );
319

Joshua Thielen's avatar
Joshua Thielen committed
320
    p_board->status = WAITING;
321
    p_board->face_bmp = SMILE_BMP;
Joshua Thielen's avatar
Joshua Thielen committed
322 323
    p_board->time = 0;

324 325 326 327 328 329 330 331 332 333 334 335 336 337
    wnd_rect.left   = p_board->pos.x;
    wnd_rect.right  = p_board->pos.x + p_board->width;
    wnd_rect.top    = p_board->pos.y;
    wnd_rect.bottom = p_board->pos.y + p_board->height;
    AdjustWindowRect(&wnd_rect, wnd_style, TRUE);

    /* Make sure the window is completely on the screen */
    MoveOnScreen(&wnd_rect);
    MoveWindow( p_board->hWnd, wnd_rect.left, wnd_rect.top,
		wnd_rect.right - wnd_rect.left,
		wnd_rect.bottom - wnd_rect.top,
		TRUE );
    RedrawWindow( p_board->hWnd, NULL, 0,
		  RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE);
Joshua Thielen's avatar
Joshua Thielen committed
338 339 340
}


341
/* Randomly places mines everywhere except the selected box. */
342
static void PlaceMines ( BOARD *p_board, int selected_col, int selected_row )
Joshua Thielen's avatar
Joshua Thielen committed
343 344 345 346 347 348
{
    int i, j;
    unsigned col, row;

    srand( (unsigned) time( NULL ) );

349 350 351
    /* Temporarily place a mine at the selected box until all the other
     * mines are placed, this avoids checking in the mine creation loop. */
    p_board->box[selected_col][selected_row].IsMine = TRUE;
Joshua Thielen's avatar
Joshua Thielen committed
352 353 354

    /* create mines */
    i = 0;
355 356 357
    while( (unsigned) i < p_board->mines ) {
        col = (int) (p_board->cols * (float) rand() / RAND_MAX + 1);
        row = (int) (p_board->rows * (float) rand() / RAND_MAX + 1);
Joshua Thielen's avatar
Joshua Thielen committed
358 359 360 361 362 363 364

        if( !p_board->box[col][row].IsMine ) {
            i++;
            p_board->box[col][row].IsMine = TRUE;
        }
    }

365 366 367
    /* Remove temporarily placed mine for selected box */
    p_board->box[selected_col][selected_row].IsMine = FALSE;

Joshua Thielen's avatar
Joshua Thielen committed
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
    /*
     * Now we label the remaining boxes with the
     * number of mines surrounding them.
     */
    for( col = 1; col < p_board->cols + 1; col++ )
    for( row = 1; row < p_board->rows + 1; row++ ) {
        for( i = -1; i <= 1; i++ )
        for( j = -1; j <= 1; j++ ) {
            if( p_board->box[col + i][row + j].IsMine ) {
                p_board->box[col][row].NumMines++ ;
            }
        }
    }
}

383
static void DrawMine( HDC hdc, HDC hMemDC, BOARD *p_board, unsigned col, unsigned row, BOOL IsPressed )
Joshua Thielen's avatar
Joshua Thielen committed
384 385 386 387
{
    MINEBMP_OFFSET offset = BOX_BMP;

    if( col == 0 || col > p_board->cols || row == 0 || row > p_board->rows )
388
           return;
Joshua Thielen's avatar
Joshua Thielen committed
389 390 391 392 393 394 395 396

    if( p_board->status == GAMEOVER ) {
        if( p_board->box[col][row].IsMine ) {
            switch( p_board->box[col][row].FlagType ) {
            case FLAG:
                offset = FLAG_BMP;
                break;
            case COMPLETE:
397
                offset = EXPLODE_BMP;
Joshua Thielen's avatar
Joshua Thielen committed
398
                break;
399 400
            case QUESTION:
                /* fall through */
Joshua Thielen's avatar
Joshua Thielen committed
401 402 403
            case NORMAL:
                offset = MINE_BMP;
            }
404
        } else {
405
            switch( p_board->box[col][row].FlagType ) {
Joshua Thielen's avatar
Joshua Thielen committed
406
            case QUESTION:
407
                offset = QUESTION_BMP;
Joshua Thielen's avatar
Joshua Thielen committed
408 409 410 411
                break;
            case FLAG:
                offset = WRONG_BMP;
                break;
412
            case NORMAL:
Joshua Thielen's avatar
Joshua Thielen committed
413
                offset = BOX_BMP;
414 415 416 417 418
                break;
            case COMPLETE:
                /* Do nothing */
                break;
            default:
419
                WINE_TRACE("Unknown FlagType during game over in DrawMine\n");
420
                break;
Joshua Thielen's avatar
Joshua Thielen committed
421
            }
422
        }
423
    } else {    /* WAITING or PLAYING */
Joshua Thielen's avatar
Joshua Thielen committed
424 425
        switch( p_board->box[col][row].FlagType ) {
        case QUESTION:
426 427
            if( !IsPressed )
                offset = QUESTION_BMP;
Joshua Thielen's avatar
Joshua Thielen committed
428
            else
429
                offset = QPRESS_BMP;
Joshua Thielen's avatar
Joshua Thielen committed
430 431 432 433
            break;
        case FLAG:
            offset = FLAG_BMP;
            break;
434
        case NORMAL:
Joshua Thielen's avatar
Joshua Thielen committed
435 436
            if( !IsPressed )
                offset = BOX_BMP;
437
            else
Joshua Thielen's avatar
Joshua Thielen committed
438
                offset = MPRESS_BMP;
439 440 441 442 443
            break;
        case COMPLETE:
            /* Do nothing */
            break;
        default:
444
            WINE_TRACE("Unknown FlagType while playing in DrawMine\n");
445
            break;
Joshua Thielen's avatar
Joshua Thielen committed
446
        }
447
    }
Joshua Thielen's avatar
Joshua Thielen committed
448

449
    if( p_board->box[col][row].FlagType == COMPLETE
450
        && !p_board->box[col][row].IsMine )
Joshua Thielen's avatar
Joshua Thielen committed
451
          offset = (MINEBMP_OFFSET) p_board->box[col][row].NumMines;
452

Joshua Thielen's avatar
Joshua Thielen committed
453
    BitBlt( hdc,
454 455 456 457
            (col - 1) * MINE_WIDTH + p_board->mines_rect.left,
            (row - 1) * MINE_HEIGHT + p_board->mines_rect.top,
            MINE_WIDTH, MINE_HEIGHT,
            hMemDC, 0, offset * MINE_HEIGHT, SRCCOPY );
Joshua Thielen's avatar
Joshua Thielen committed
458 459
}

460
static void DrawMines ( HDC hdc, HDC hMemDC, BOARD *p_board )
461 462 463 464 465 466 467 468 469 470 471 472 473
{
    HGDIOBJ hOldObj;
    unsigned col, row;
    hOldObj = SelectObject (hMemDC, p_board->hMinesBMP);

    for( row = 1; row <= p_board->rows; row++ ) {
      for( col = 1; col <= p_board->cols; col++ ) {
        DrawMine( hdc, hMemDC, p_board, col, row, FALSE );
      }
    }
    SelectObject( hMemDC, hOldObj );
}

474
static void DrawLeds( HDC hdc, HDC hMemDC, BOARD *p_board, int number, int x, int y )
Joshua Thielen's avatar
Joshua Thielen committed
475
{
476
    HGDIOBJ hOldObj;
Joshua Thielen's avatar
Joshua Thielen committed
477
    unsigned led[3], i;
478
    int count;
Joshua Thielen's avatar
Joshua Thielen committed
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498

    count = number;
    if( count < 1000 ) {
        if( count >= 0 ) {
            led[0] = count / 100 ;
            count -= led[0] * 100;
        }
        else {
            led[0] = 10; /* negative sign */
            count = -count;
        }
        led[1] = count / 10;
        count -= led[1] * 10;
        led[2] = count;
    }
    else {
        for( i = 0; i < 3; i++ )
            led[i] = 10;
    }

499
    hOldObj = SelectObject (hMemDC, p_board->hLedsBMP);
500

Joshua Thielen's avatar
Joshua Thielen committed
501 502 503 504 505 506
    for( i = 0; i < 3; i++ ) {
        BitBlt( hdc,
            i * LED_WIDTH + x,
            y,
            LED_WIDTH,
            LED_HEIGHT,
507 508 509
            hMemDC,
            0,
            led[i] * LED_HEIGHT,
Joshua Thielen's avatar
Joshua Thielen committed
510 511
            SRCCOPY);
    }
512

513
    SelectObject( hMemDC, hOldObj );
Joshua Thielen's avatar
Joshua Thielen committed
514 515 516
}


517
static void DrawFace( HDC hdc, HDC hMemDC, BOARD *p_board )
Joshua Thielen's avatar
Joshua Thielen committed
518
{
519
    HGDIOBJ hOldObj;
520 521

    hOldObj = SelectObject (hMemDC, p_board->hFacesBMP);
Joshua Thielen's avatar
Joshua Thielen committed
522 523 524 525 526 527 528

    BitBlt( hdc,
        p_board->face_rect.left,
        p_board->face_rect.top,
        FACE_WIDTH,
        FACE_HEIGHT,
        hMemDC, 0, p_board->face_bmp * FACE_HEIGHT, SRCCOPY);
529

530
    SelectObject( hMemDC, hOldObj );
Joshua Thielen's avatar
Joshua Thielen committed
531 532 533
}


534
static void DrawBoard( HDC hdc, HDC hMemDC, PAINTSTRUCT *ps, BOARD *p_board )
Joshua Thielen's avatar
Joshua Thielen committed
535
{
536 537 538
    RECT tmp_rect;

    if( IntersectRect( &tmp_rect, &ps->rcPaint, &p_board->counter_rect ) )
539 540 541
        DrawLeds( hdc, hMemDC, p_board, p_board->mines - p_board->num_flags,
                  p_board->counter_rect.left,
                  p_board->counter_rect.top );
Joshua Thielen's avatar
Joshua Thielen committed
542

543
    if( IntersectRect( &tmp_rect, &ps->rcPaint, &p_board->timer_rect ) )
544
        DrawLeds( hdc, hMemDC, p_board, p_board->time,
545
                  p_board->timer_rect.left,
546
                  p_board->timer_rect.top );
547 548

    if( IntersectRect( &tmp_rect, &ps->rcPaint, &p_board->face_rect ) )
549
        DrawFace( hdc, hMemDC, p_board );
550 551

    if( IntersectRect( &tmp_rect, &ps->rcPaint, &p_board->mines_rect ) )
552
        DrawMines( hdc, hMemDC, p_board );
553
}
Joshua Thielen's avatar
Joshua Thielen committed
554 555


556
static void AddFlag( BOARD *p_board, unsigned col, unsigned row )
Joshua Thielen's avatar
Joshua Thielen committed
557
{
558 559 560 561 562 563 564 565 566
    if( p_board->box[col][row].FlagType != COMPLETE ) {
        switch( p_board->box[col][row].FlagType ) {
        case FLAG:
            if( p_board->IsMarkQ )
                p_board->box[col][row].FlagType = QUESTION;
            else
                p_board->box[col][row].FlagType = NORMAL;
            p_board->num_flags--;
            break;
567

568 569 570
        case QUESTION:
            p_board->box[col][row].FlagType = NORMAL;
            break;
Joshua Thielen's avatar
Joshua Thielen committed
571

572 573 574 575
        default:
            p_board->box[col][row].FlagType = FLAG;
            p_board->num_flags++;
        }
Joshua Thielen's avatar
Joshua Thielen committed
576
    }
577
}
Joshua Thielen's avatar
Joshua Thielen committed
578

579

580
static void UnpressBox( BOARD *p_board, unsigned col, unsigned row )
581 582 583 584
{
    HDC hdc;
    HGDIOBJ hOldObj;
    HDC hMemDC;
585

586 587 588
    hdc = GetDC( p_board->hWnd );
    hMemDC = CreateCompatibleDC( hdc );
    hOldObj = SelectObject( hMemDC, p_board->hMinesBMP );
589

590 591 592 593 594 595 596 597
    DrawMine( hdc, hMemDC, p_board, col, row, FALSE );

    SelectObject( hMemDC, hOldObj );
    DeleteDC( hMemDC );
    ReleaseDC( p_board->hWnd, hdc );
}


598
static void UnpressBoxes( BOARD *p_board, unsigned col, unsigned row )
599 600 601 602 603 604 605 606 607 608
{
    int i, j;

    for( i = -1; i <= 1; i++ )
      for( j = -1; j <= 1; j++ ) {
        UnpressBox( p_board, col + i, row + j );
      }
}


609
static void PressBox( BOARD *p_board, unsigned col, unsigned row )
610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626
{
    HDC hdc;
    HGDIOBJ hOldObj;
    HDC hMemDC;

    hdc = GetDC( p_board->hWnd );
    hMemDC = CreateCompatibleDC( hdc );
    hOldObj = SelectObject (hMemDC, p_board->hMinesBMP);

    DrawMine( hdc, hMemDC, p_board, col, row, TRUE );

    SelectObject( hMemDC, hOldObj );
    DeleteDC( hMemDC );
    ReleaseDC( p_board->hWnd, hdc );
}


627
static void PressBoxes( BOARD *p_board, unsigned col, unsigned row )
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
{
    int i, j;

    for( i = -1; i <= 1; i++ )
      for( j = -1; j <= 1; j++ ) {
        p_board->box[col + i][row + j].IsPressed = TRUE;
        PressBox( p_board, col + i, row + j );
    }

    for( i = -1; i <= 1; i++ )
      for( j = -1; j <= 1; j++ ) {
        if( !p_board->box[p_board->press.x + i][p_board->press.y + j].IsPressed )
            UnpressBox( p_board, p_board->press.x + i, p_board->press.y + j );
    }

    for( i = -1; i <= 1; i++ )
      for( j = -1; j <= 1; j++ ) {
        p_board->box[col + i][row + j].IsPressed = FALSE;
        PressBox( p_board, col + i, row + j );
    }

    p_board->press.x = col;
    p_board->press.y = row;
}


654
static void CompleteBox( BOARD *p_board, unsigned col, unsigned row )
655 656 657 658 659 660 661 662 663 664 665 666
{
    int i, j;

    if( p_board->box[col][row].FlagType != COMPLETE &&
            p_board->box[col][row].FlagType != FLAG &&
            col > 0 && col < p_board->cols + 1 &&
            row > 0 && row < p_board->rows + 1 ) {
        p_board->box[col][row].FlagType = COMPLETE;

        if( p_board->box[col][row].IsMine ) {
            p_board->face_bmp = DEAD_BMP;
            p_board->status = GAMEOVER;
667
        }
668 669
        else if( p_board->status != GAMEOVER )
            p_board->boxes_left--;
670

671 672 673 674 675 676 677 678
        if( p_board->box[col][row].NumMines == 0 )
        {
            for( i = -1; i <= 1; i++ )
            for( j = -1; j <= 1; j++ )
                CompleteBox( p_board, col + i, row + j  );
        }
    }
}
679 680


681
static void CompleteBoxes( BOARD *p_board, unsigned col, unsigned row )
682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698
{
    unsigned numFlags = 0;
    int i, j;

    if( p_board->box[col][row].FlagType == COMPLETE ) {
        for( i = -1; i <= 1; i++ )
          for( j = -1; j <= 1; j++ ) {
            if( p_board->box[col+i][row+j].FlagType == FLAG )
                numFlags++;
          }

        if( numFlags == p_board->box[col][row].NumMines ) {
            for( i = -1; i <= 1; i++ )
              for( j = -1; j <= 1; j++ ) {
                if( p_board->box[col+i][row+j].FlagType != FLAG )
                    CompleteBox( p_board, col+i, row+j );
              }
Joshua Thielen's avatar
Joshua Thielen committed
699 700 701 702
        }
    }
}

703

704
static void TestMines( BOARD *p_board, POINT pt, int msg )
Joshua Thielen's avatar
Joshua Thielen committed
705 706
{
    BOOL draw = TRUE;
707
    int col, row;
Joshua Thielen's avatar
Joshua Thielen committed
708 709 710

    col = (pt.x - p_board->mines_rect.left) / MINE_WIDTH + 1;
    row = (pt.y - p_board->mines_rect.top ) / MINE_HEIGHT + 1;
711

Joshua Thielen's avatar
Joshua Thielen committed
712 713 714
    switch ( msg ) {
    case WM_LBUTTONDOWN:
        if( p_board->press.x != col || p_board->press.y != row ) {
715
            UnpressBox( p_board,
Joshua Thielen's avatar
Joshua Thielen committed
716 717 718
                    p_board->press.x, p_board->press.y );
            p_board->press.x = col;
            p_board->press.y = row;
719 720 721
            PressBox( p_board, col, row );
        }
        draw = FALSE;
Joshua Thielen's avatar
Joshua Thielen committed
722 723 724 725
        break;

    case WM_LBUTTONUP:
        if( p_board->press.x != col || p_board->press.y != row )
726
            UnpressBox( p_board,
Joshua Thielen's avatar
Joshua Thielen committed
727 728 729
                    p_board->press.x, p_board->press.y );
        p_board->press.x = 0;
        p_board->press.y = 0;
730 731 732
        if( p_board->box[col][row].FlagType != FLAG
            && p_board->status != PLAYING )
        {
733
            p_board->status = PLAYING;
734 735
            PlaceMines( p_board, col, row );
        }
Joshua Thielen's avatar
Joshua Thielen committed
736 737 738 739 740
        CompleteBox( p_board, col, row );
        break;

    case WM_MBUTTONDOWN:
        PressBoxes( p_board, col, row );
741
        draw = FALSE;
Joshua Thielen's avatar
Joshua Thielen committed
742 743 744 745
        break;

    case WM_MBUTTONUP:
        if( p_board->press.x != col || p_board->press.y != row )
746
            UnpressBoxes( p_board,
Joshua Thielen's avatar
Joshua Thielen committed
747 748 749 750 751 752 753 754
                    p_board->press.x, p_board->press.y );
        p_board->press.x = 0;
        p_board->press.y = 0;
        CompleteBoxes( p_board, col, row );
        break;

    case WM_RBUTTONDOWN:
        AddFlag( p_board, col, row );
755 756
        break;
    default:
757
        WINE_TRACE("Unknown message type received in TestMines\n");
Joshua Thielen's avatar
Joshua Thielen committed
758 759
        break;
    }
760

Joshua Thielen's avatar
Joshua Thielen committed
761 762
    if( draw )
    {
763
        RedrawWindow( p_board->hWnd, NULL, 0,
Joshua Thielen's avatar
Joshua Thielen committed
764 765
            RDW_INVALIDATE | RDW_UPDATENOW );
    }
766
}
Joshua Thielen's avatar
Joshua Thielen committed
767 768


769
static void TestFace( BOARD *p_board, POINT pt, int msg )
Joshua Thielen's avatar
Joshua Thielen committed
770 771 772 773 774 775
{
    if( p_board->status == PLAYING || p_board->status == WAITING ) {
        if( msg == WM_LBUTTONDOWN || msg == WM_MBUTTONDOWN )
            p_board->face_bmp = OOH_BMP;
        else p_board->face_bmp = SMILE_BMP;
    }
776
    else if( p_board->status == GAMEOVER )
Joshua Thielen's avatar
Joshua Thielen committed
777
        p_board->face_bmp = DEAD_BMP;
778
    else if( p_board->status == WON )
Joshua Thielen's avatar
Joshua Thielen committed
779 780
            p_board->face_bmp = COOL_BMP;

781 782
    if( PtInRect( &p_board->face_rect, pt ) ) {
        if( msg == WM_LBUTTONDOWN )
Joshua Thielen's avatar
Joshua Thielen committed
783
            p_board->face_bmp = SPRESS_BMP;
784 785 786

        if( msg == WM_LBUTTONUP )
            CreateBoard( p_board );
Joshua Thielen's avatar
Joshua Thielen committed
787
    }
788

789
    RedrawWindow( p_board->hWnd, &p_board->face_rect, 0,
Joshua Thielen's avatar
Joshua Thielen committed
790 791 792 793
        RDW_INVALIDATE | RDW_UPDATENOW );
}


794
static void TestBoard( HWND hWnd, BOARD *p_board, int x, int y, int msg )
Joshua Thielen's avatar
Joshua Thielen committed
795
{
796 797
    POINT pt;
    unsigned col,row;
Joshua Thielen's avatar
Joshua Thielen committed
798

799 800
    pt.x = x;
    pt.y = y;
801

802 803 804 805 806 807 808 809 810
    if( PtInRect( &p_board->mines_rect, pt ) && p_board->status != GAMEOVER
    && p_board->status != WON )
        TestMines( p_board, pt, msg );
    else {
        UnpressBoxes( p_board,
            p_board->press.x,
            p_board->press.y );
        p_board->press.x = 0;
        p_board->press.y = 0;
811
    }
Joshua Thielen's avatar
Joshua Thielen committed
812

813 814
    if( p_board->boxes_left == 0 ) {
        p_board->status = WON;
Joshua Thielen's avatar
Joshua Thielen committed
815

816 817 818 819 820 821 822
        if (p_board->num_flags < p_board->mines) {
            for( row = 1; row <= p_board->rows; row++ ) {
                for( col = 1; col <= p_board->cols; col++ ) {
                    if (p_board->box[col][row].IsMine && p_board->box[col][row].FlagType != FLAG)
                        p_board->box[col][row].FlagType = FLAG;
                }
            }
Joshua Thielen's avatar
Joshua Thielen committed
823

824
            p_board->num_flags = p_board->mines;
825

826 827
            RedrawWindow( p_board->hWnd, NULL, 0,
                RDW_INVALIDATE | RDW_UPDATENOW );
Joshua Thielen's avatar
Joshua Thielen committed
828 829
        }

830 831 832
        if( p_board->difficulty != CUSTOM &&
                    p_board->time < p_board->best_time[p_board->difficulty] ) {
            p_board->best_time[p_board->difficulty] = p_board->time;
Joshua Thielen's avatar
Joshua Thielen committed
833

834 835 836 837
            DialogBoxParamW( p_board->hInst, MAKEINTRESOURCEW(DLG_CONGRATS), hWnd,
                             CongratsDlgProc, (LPARAM) p_board);
            DialogBoxParamW( p_board->hInst, MAKEINTRESOURCEW(DLG_TIMES), hWnd,
                             TimesDlgProc, (LPARAM) p_board);
838 839
        }
    }
840
    TestFace( p_board, pt, msg );
Joshua Thielen's avatar
Joshua Thielen committed
841 842 843
}


844
static LRESULT WINAPI MainProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Joshua Thielen's avatar
Joshua Thielen committed
845
{
846
    HDC hdc;
847 848 849
    PAINTSTRUCT ps;
    HMENU hMenu;
    static BOARD board;
Joshua Thielen's avatar
Joshua Thielen committed
850

851 852
    switch( msg ) {
    case WM_CREATE:
853
        board.hInst = ((LPCREATESTRUCTW) lParam)->hInstance;
854 855 856 857
        board.hWnd = hWnd;
        InitBoard( &board );
        CreateBoard( &board );
        return 0;
858

859 860 861
    case WM_PAINT:
      {
        HDC hMemDC;
862

863 864 865
        WINE_TRACE("WM_PAINT\n");
        hdc = BeginPaint( hWnd, &ps );
        hMemDC = CreateCompatibleDC( hdc );
Joshua Thielen's avatar
Joshua Thielen committed
866

867
        DrawBoard( hdc, hMemDC, &ps, &board );
Joshua Thielen's avatar
Joshua Thielen committed
868

869 870
        DeleteDC( hMemDC );
        EndPaint( hWnd, &ps );
Joshua Thielen's avatar
Joshua Thielen committed
871

872 873
        return 0;
      }
Joshua Thielen's avatar
Joshua Thielen committed
874

875 876 877 878 879
    case WM_MOVE:
        WINE_TRACE("WM_MOVE\n");
        board.pos.x = (short)LOWORD(lParam);
        board.pos.y = (short)HIWORD(lParam);
        return 0;
Joshua Thielen's avatar
Joshua Thielen committed
880

881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939
    case WM_DESTROY:
        SaveBoard( &board );
        DestroyBoard( &board );
        PostQuitMessage( 0 );
        return 0;

    case WM_TIMER:
        if( board.status == PLAYING ) {
            board.time++;
	    RedrawWindow( hWnd, &board.timer_rect, 0,
			  RDW_INVALIDATE | RDW_UPDATENOW );
        }
        return 0;

    case WM_LBUTTONDOWN:
        WINE_TRACE("WM_LBUTTONDOWN\n");
        if( wParam & MK_RBUTTON )
            msg = WM_MBUTTONDOWN;
        TestBoard( hWnd, &board, (short)LOWORD(lParam), (short)HIWORD(lParam), msg );
        SetCapture( hWnd );
        return 0;

    case WM_LBUTTONUP:
        WINE_TRACE("WM_LBUTTONUP\n");
        if( wParam & MK_RBUTTON )
            msg = WM_MBUTTONUP;
        TestBoard( hWnd, &board, (short)LOWORD(lParam), (short)HIWORD(lParam), msg );
        ReleaseCapture();
        return 0;

    case WM_RBUTTONDOWN:
        WINE_TRACE("WM_RBUTTONDOWN\n");
        if( wParam & MK_LBUTTON ) {
            board.press.x = 0;
            board.press.y = 0;
            msg = WM_MBUTTONDOWN;
        }
        TestBoard( hWnd, &board, (short)LOWORD(lParam), (short)HIWORD(lParam), msg );
        return 0;

    case WM_RBUTTONUP:
        WINE_TRACE("WM_RBUTTONUP\n");
        if( wParam & MK_LBUTTON )
            msg = WM_MBUTTONUP;
        TestBoard( hWnd, &board, (short)LOWORD(lParam), (short)HIWORD(lParam), msg );
        return 0;

    case WM_MBUTTONDOWN:
        WINE_TRACE("WM_MBUTTONDOWN\n");
        TestBoard( hWnd, &board, (short)LOWORD(lParam), (short)HIWORD(lParam), msg );
        return 0;

    case WM_MBUTTONUP:
        WINE_TRACE("WM_MBUTTONUP\n");
        TestBoard( hWnd, &board, (short)LOWORD(lParam), (short)HIWORD(lParam), msg );
        return 0;

    case WM_MOUSEMOVE:
    {
940 941
        if( ( wParam & MK_MBUTTON ) ||
            ( ( wParam & MK_LBUTTON ) && ( wParam & MK_RBUTTON ) ) ) {
942 943 944 945 946 947 948 949 950 951 952 953
            msg = WM_MBUTTONDOWN;
        }
        else if( wParam & MK_LBUTTON ) {
            msg = WM_LBUTTONDOWN;
        }
        else {
            return 0;
        }

        TestBoard( hWnd, &board, (short)LOWORD(lParam), (short)HIWORD(lParam),  msg );

        return 0;
Joshua Thielen's avatar
Joshua Thielen committed
954 955
    }

956 957 958 959 960
    case WM_COMMAND:
        switch(LOWORD(wParam)) {
        case IDM_NEW:
            CreateBoard( &board );
            return 0;
Joshua Thielen's avatar
Joshua Thielen committed
961

962 963 964 965 966 967 968 969
        case IDM_MARKQ:
            hMenu = GetMenu( hWnd );
            board.IsMarkQ = !board.IsMarkQ;
            if( board.IsMarkQ )
                CheckMenuItem( hMenu, IDM_MARKQ, MF_CHECKED );
            else
                CheckMenuItem( hMenu, IDM_MARKQ, MF_UNCHECKED );
            return 0;
Joshua Thielen's avatar
Joshua Thielen committed
970

971 972 973 974
        case IDM_BEGINNER:
            SetDifficulty( &board, BEGINNER );
            CreateBoard( &board );
            return 0;
Joshua Thielen's avatar
Joshua Thielen committed
975

976 977 978 979
        case IDM_ADVANCED:
            SetDifficulty( &board, ADVANCED );
            CreateBoard( &board );
            return 0;
980

981 982 983 984
        case IDM_EXPERT:
            SetDifficulty( &board, EXPERT );
            CreateBoard( &board );
            return 0;
985

986 987 988 989 990 991
        case IDM_CUSTOM:
            SetDifficulty( &board, CUSTOM );
            CreateBoard( &board );
            return 0;

        case IDM_EXIT:
992
            SendMessageW( hWnd, WM_CLOSE, 0, 0);
993
            return 0;
Joshua Thielen's avatar
Joshua Thielen committed
994

995
        case IDM_TIMES:
996 997
            DialogBoxParamW( board.hInst, MAKEINTRESOURCEW(DLG_TIMES), hWnd,
                             TimesDlgProc, (LPARAM) &board);
998
            return 0;
Joshua Thielen's avatar
Joshua Thielen committed
999

1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013
        case IDM_ABOUT:
        {
            WCHAR appname[256], other[256];
            LoadStringW( board.hInst, IDS_APPNAME, appname, sizeof(appname)/sizeof(WCHAR) );
            LoadStringW( board.hInst, IDS_ABOUT, other, sizeof(other)/sizeof(WCHAR) );
            ShellAboutW( hWnd, appname, other,
                         LoadImageA( board.hInst, "WINEMINE", IMAGE_ICON, 48, 48, LR_SHARED ));
            return 0;
        }
        default:
            WINE_TRACE("Unknown WM_COMMAND command message received\n");
            break;
        }
    }
1014
    return DefWindowProcW( hWnd, msg, wParam, lParam );
1015 1016
}

1017
int WINAPI wWinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPWSTR cmdline, int cmdshow )
Joshua Thielen's avatar
Joshua Thielen committed
1018
{
1019
    MSG msg;
1020
    WNDCLASSEXW wc;
1021 1022
    HWND hWnd;
    HACCEL haccel;
1023
    WCHAR appname[20];
1024

1025
    LoadStringW( hInst, IDS_APPNAME, appname, sizeof(appname)/sizeof(WCHAR));
1026

1027
    wc.cbSize = sizeof(wc);
1028 1029 1030 1031 1032
    wc.style = 0;
    wc.lpfnWndProc = MainProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInst;
1033 1034
    wc.hIcon = LoadIconW( hInst, MAKEINTRESOURCEW(IDI_WINEMINE) );
    wc.hCursor = LoadCursorW( 0, (LPWSTR)IDI_APPLICATION );
1035
    wc.hbrBackground = GetStockObject( BLACK_BRUSH );
1036
    wc.lpszMenuName = MAKEINTRESOURCEW(IDM_WINEMINE);
1037
    wc.lpszClassName = appname;
1038
    wc.hIconSm = LoadImageW( hInst, MAKEINTRESOURCEW(IDI_WINEMINE), IMAGE_ICON,
1039
                            GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_SHARED );
1040

1041 1042
    if (!RegisterClassExW(&wc)) ExitProcess(1);
    hWnd = CreateWindowW( appname, appname,
1043 1044 1045 1046 1047 1048 1049 1050 1051
	wnd_style,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        0, 0, hInst, NULL );

    if (!hWnd) ExitProcess(1);

    ShowWindow( hWnd, cmdshow );
    UpdateWindow( hWnd );

1052
    haccel = LoadAcceleratorsW( hInst, MAKEINTRESOURCEW(IDA_WINEMINE) );
1053 1054
    SetTimer( hWnd, ID_TIMER, 1000, NULL );

1055 1056
    while( GetMessageW(&msg, 0, 0, 0) ) {
        if (!TranslateAcceleratorW( hWnd, haccel, &msg ))
1057 1058
            TranslateMessage( &msg );

1059
        DispatchMessageW( &msg );
1060 1061
    }
    return msg.wParam;
Joshua Thielen's avatar
Joshua Thielen committed
1062
}