📄 whamster.c
字号:
if (!CreatePipe(&p_in, &c_out, &sa, 0)) { stop(0, E_POPEN); return; } /* create pipe child -> parent */ if (!CreatePipe(&c_in, &p_out, &sa, 0)) { CloseHandle(c_out); /* create pipe parent -> child */ stop(0, E_POPEN); return; /* and then set the child ends */ } /* of the pipes as standard handles */ AllocConsole(); /* for a newly created console */ SetStdHandle(STD_OUTPUT_HANDLE, c_out); SetStdHandle(STD_INPUT_HANDLE, c_in); /* --- start hamster process --- */ si.cb = sizeof(STARTUPINFO); si.lpReserved = NULL; /* initialize */ si.lpReserved2 = NULL; /* process */ si.cbReserved2 = 0; /* startup */ si.lpDesktop = NULL; /* information */ si.lpTitle = appdata.fn_hms; si.dwFlags = 0; ok = CreateProcess(NULL, /* create a child process */ appdata.fn_hms, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi); FreeConsole(); /* free console and close handles */ CloseHandle(c_out); CloseHandle(c_in); if (!ok) { stop(0, E_PROCESS); return; } process = pi.hProcess; /* note the process handle */ /* --- start pipe input thread --- */ thread = CreateThread(NULL, /* create pipe input thread */ 0, (LPTHREAD_START_ROUTINE)ip_pipe, NULL, 0, &id); if (!thread) stop(0, E_THREAD);} /* start() *//*---------------------------------------------------------------------- Window Function----------------------------------------------------------------------*/LRESULT CALLBACK wp_main (HWND hwnd, UINT msg, WPARAM wp, LPARAM lp){ /* --- main window procedure */ static PAINTSTRUCT ps; /* for BeginPaint call */ static MENUITEMINFO mii; /* for menu customization */ HDC hdc; /* handle of device context */ int x, y, dx, dy; /* coordinates and distances */ short t, chg; /* temporary buffer */ switch (msg) { /* evaluate message */ case WM_PAINT: /* --- if to paint window */ if (process) { /* if hamster process is running, */ SuspendThread(thread); /* suspend thread while drawing */ if (hmscb[0].sprite) /* if a hamster sprite exists */ spr_undraw(hmscb[0].sprite); } /* undraw sprite (for savety) */ hdc = BeginPaint(hwnd, &ps); if (!hdc) return 0; /* get device context for drawing */ mz_exts(maze, &dx, &dy); /* get maze extensions */ for (x = dx; --x >= 0; ) /* and traverse fields */ for (y = dy; --y >= 0; ) draw_field(hdc, x, y);/* draw maze fields */ SetWindowText(hmain, PRGNAME); EndPaint(hwnd, &ps); /* release device context */ if (process) { /* if hamster process is running, */ if (hmscb[0].sprite) /* if a hamster sprite exists */ spr_draw(hmscb[0].sprite, INT_MIN, INT_MIN); ResumeThread(thread); /* redraw hamster sprite and */ } break; /* resume suspended thread */ case WM_INITMENUPOPUP: /* --- if menu opened */ SetWindowText(hmain, PRGNAME); return 0; case WM_COMMAND: /* --- if menu item selected */ switch (wp) { /* evaluate item */ case MI_RELOAD: /* Menu Item `Reload Maze...' */ if (mz_file(MZ_LOAD) == 0) resize(hwnd); return 0; /* resize window */ case MI_LOAD: /* Menu Item `Load Maze...' */ if (mz_file(MZ_LOAD|MZ_NEW) == 0) resize(hwnd); return 0; /* resize window */ case MI_SAVE: /* Menu Item `Save Maze...' */ mz_file(MZ_SAVE); /* save maze under old name */ return 0; case MI_SAVEAS: /* Menu Item `Save Maze As...' */ mz_file(MZ_SAVE|MZ_NEW); return 0; /* select file and save maze */ case MI_SELECT: /* Menu Item `Select Hamster...' */ select(); return 0; /* select a hamster program */ case MI_QUIT: /* Menu Item 'Quit' */ if (process) { /* if a hamster is running */ TerminateProcess(process, 0); process = NULL; } DestroyWindow(hwnd); /* stop hamster process */ return 0; /* and destroy window */ case MI_REDRAW: /* Menu Item 'Redraw' */ InvalidateRect(hwnd, NULL, 0); return 0; /* invalidate window contents */ case MI_SIZE: /* Menu Item 'Set Maze Size...' */ if (DialogBox(hinst, MKIRSC(DB_SIZE), hwnd, dp_size) == 0) resize(hwnd); /* if a new maze size was set, */ return 0; /* resize window */ case MI_RANDOM: /* Menu Item 'Randomize Maze...' */ if (DialogBox(hinst, MKIRSC(DB_RANDOM), hwnd, dp_random) == 0) InvalidateRect(hwnd, NULL, 0); return 0; /* initialize and redraw maze */ case MI_CLEAR: /* Menu Item 'Clear Maze' */ mz_init(maze, 0, 0.0F, 0, 0); InvalidateRect(hwnd, NULL, 0); return 0; /* clear and redraw maze */ case MI_SPEED: /* Menu Item 'Set Hamster Speed...' */ DialogBox(hinst, MKIRSC(DB_SPEED), hwnd, dp_speed); return 0; /* get hamster speed */ case MI_START: /* Menu Item `Start Hamster' */ start(); return 0; /* start hamster process */ case MI_STOP: /* Menu Item `Stop Hamster' */ stop(0,OK); return 0; /* stop hamster process */ case MI_ABOUT: /* Menu Item 'About' */ DialogBox(hinst, MKIRSC(DB_ABOUT), hwnd, dp_about); return 0; /* show dialog box 'About WHamster' */ } break; case WM_LBUTTONDOWN: /* if left mouse button pressed */ if (thread) break; /* if hamster is running, abort */ hdc = GetDC(hwnd); /* get handle of device context */ x = LOWORD(lp) -xoff; /* compute coordinates */ y = yoff -HIWORD(lp); /* relative to lower left corner */ if (wp & MK_CONTROL) { /* if control key pressed, */ x /= FIELDWD; y /= FIELDWD; /* remove all walls */ mz_setfld(maze, x, y, MZ_WALLS, 0); } else if (wp & MK_SHIFT) { /* if shift key pressed */ mz_getpos(maze, &dx, &dy); x /= FIELDWD; y /= FIELDWD; /* get coordinates of old field, */ mz_setpos(maze, x, y); /* compute coordinates of new */ draw_field(hdc, dx, dy); } /* and redraw old field */ else { /* if shift key not pressed */ dx = x & 0x0f; dy = y & 0x0f; t = 0; if (dx >= FIELDWD/2) { t |= MZ_EAST; dx = FIELDWD-1 -dx; } else { t |= MZ_WEST; } if (dy >= FIELDWD/2) { t |= MZ_NORTH; dy = FIELDWD-1 -dy; } else { t |= MZ_SOUTH; } t &= (dx <= dy) ? MZ_WEST|MZ_EAST : MZ_SOUTH|MZ_NORTH; dx = (t & MZ_WEST) ? -1 : 0; /* get offsets to */ dy = (t & MZ_SOUTH) ? -1 : 0; /* next field */ x /= FIELDWD; y /= FIELDWD; /* compute field coordinates */ t ^= mz_getfld(maze, x, y); mz_setfld(maze, x, y, MZ_WALLS, t); } /* toggle wall flag */ draw_field(hdc, x, y); /* redraw changed field */ ReleaseDC(hwnd, hdc); /* and clear info field */ SetWindowText(hmain, PRGNAME); break; case WM_MBUTTONDOWN: /* if middle mouse button pressed */ case WM_RBUTTONDOWN: /* or if right mouse button pressed */ if (thread) break; /* if hamster is running, abort */ x = LOWORD(lp) -xoff; /* compute coordinates */ y = yoff -HIWORD(lp); /* relative to lower left corner */ x /= FIELDWD; y /= FIELDWD; mz_getpos(maze, &dx,&dy); /* get initial position */ if ((x == dx) && (y == dy)) break; /* do not place corn on home field */ if (wp & MK_CONTROL) /* if control key pressed, */ t = chg = 0; /* clear field */ else { /* if control key not pressed */ t = mz_getfld(maze, x, y) & MZ_ITEMS; chg = (wp & MK_SHIFT) ? 5 : 1; if (msg == WM_MBUTTONDOWN) chg = -chg; } /* get change of corn heap */ t = (chg == 0) ? 0 : ((t +chg +(MAXHEAP+1)) %(MAXHEAP+1)); mz_setfld(maze, x, y, MZ_ITEMS, t); hdc = GetDC(hwnd); /* set new corn heap */ draw_field(hdc, x, y); /* and redraw field */ ReleaseDC(hwnd, hdc); /* release device context */ sprintf(buf, "%s %10d", PRGNAME, t); SetWindowText(hmain, buf);/* show new heap size */ break; /* in window title */ case WM_CLOSE: /* window closed */ case WM_DESTROY: /* or destroyed */ stop(0, E_NONE); /* stop hamster thread */ PostQuitMessage(0); /* terminate program */ return 0; } return DefWindowProc(hwnd, msg, wp, lp);} /* wp_main() *//*---------------------------------------------------------------------- Main Program----------------------------------------------------------------------*/int WINAPI WinMain (HINSTANCE hcurr, HINSTANCE hprev, LPSTR cmdln, int cmd){ /* --- main function */ WNDCLASS wc; /* window class */ RECT rc; /* window rectangle */ MSG msg; /* message */ /* --- create window class --- */ hinst = hcurr; /* note instance handle */ if (!hprev) { /* if first instance of this program */ wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = wp_main; wc.cbClsExtra = wc.cbWndExtra = 0; wc.hInstance = hinst; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = GetStockObject(WHITE_BRUSH); wc.lpszMenuName = MKIRSC(MN_MAIN); wc.lpszClassName = "HamsterClass"; if (!RegisterClass(&wc)) /* register class */ return 0; /* of main window */ } /* --- create a maze --- */ srand((unsigned)time(NULL)); /* initialize random number generator */ maze = mz_create(appdata.xext, appdata.yext); if (!maze) { error(E_NOMEM); return 0; } xoff = 1; yoff = appdata.yext *FIELDWD; /* --- get brushes --- */ br_white = GetStockObject(WHITE_BRUSH); br_grey = GetStockObject(LTGRAY_BRUSH); br_yellow = CreateSolidBrush(RGB(0xff, 0xff, 0x00)); /* --- get pens --- */ pen_white = GetStockObject(WHITE_PEN); pen_black = GetStockObject(BLACK_PEN); pen_orange = CreatePen(PS_SOLID, 1, RGB(0xff, 0xa5, 0x00)); /* --- load bitmaps --- */ hms_bmap = LoadBitmap(hinst, MKIRSC(BM_HAMSTER)); if (!hms_bmap) return 0; /* load hamster and mask bitmap */ hms_mask = LoadBitmap(hinst, MKIRSC(BM_MASK)); if (!hms_mask) { DeleteObject(hms_bmap); return 0; } /* --- create window --- */ rc.left = rc.top = 0; /* compute initial window size */ rc.right = appdata.xext *FIELDWD +1; rc.bottom = appdata.yext *FIELDWD +1; AdjustWindowRect(&rc, WINSTYLE, 1); hmain = CreateWindow("HamsterClass", PRGNAME, WINSTYLE, 30, 30, rc.right-rc.left, rc.bottom-rc.top, NULL, NULL, hinst, NULL); if (!hmain) return 0; /* create main window */ ShowWindow(hmain, cmd); /* open and */ UpdateWindow(hmain); /* update main window */ /* --- dispatch messages --- */ while (GetMessage(&msg, NULL, 0, 0) > 0) { TranslateMessage(&msg); /* get messages, translate */ DispatchMessage (&msg); /* and dispatch them */ } /* --- clean up --- */ DeleteObject(br_yellow); /* delete created brush */ DeleteObject(pen_orange); /* delete created pen */ DeleteObject(hms_bmap); /* delete loaded bitmaps */ DeleteObject(hms_mask); mz_delete(maze); /* delete maze */ return msg.wParam;} /* WinMain() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -