main.cpp
Upload User: edingdan
Upload Date: 2020-03-19
Package Size: 8486k
Code Size: 19k
Category:

AI-NN-PR

Development Platform:

Visual C++

  1. #pragma warning (disable:4786)
  2. #include <windows.h>
  3. #include <time.h>
  4. //need to include this for the toolbar stuff
  5. #include <commctrl.h>
  6. #pragma comment(lib, "comctl32.lib")
  7. #include "constants.h"
  8. #include "misc/utils.h"
  9. #include "Time/PrecisionTimer.h"
  10. #include "Pathfinder.h"
  11. #include "resource.h"
  12. #include "misc/Cgdi.h"
  13. #include "misc/WindowUtils.h"
  14. //need to define a custom message so that the backbuffer can be resized to 
  15. //accomodate the toolbar
  16. #define UM_TOOLBAR_HAS_BEEN_CREATED (WM_USER + 33)
  17. //--------------------------------- Globals ------------------------------
  18. //
  19. //------------------------------------------------------------------------
  20. const char* g_szApplicationName = "PathFinder";
  21. const char* g_szWindowClassName = "MyWindowClass";
  22. Pathfinder* g_Pathfinder;
  23. //global toolbar handle
  24. HWND g_hwndToolbar;
  25. //------------------------- RedrawDisplay ---------------------------------
  26. //
  27. //  Call this to refresh the client window
  28. //------------------------------------------------------------------------
  29. void RedrawDisplay(HWND hwnd)
  30. {
  31.   InvalidateRect(hwnd, NULL, TRUE);
  32.   UpdateWindow(hwnd);
  33. }
  34. //----------------------- ResizeToCorrectClientArea ---------------------------
  35. //
  36. //  resizes the client are taking into account any toolbars and any menus
  37. //-----------------------------------------------------------------------------
  38. void ResizeToCorrectClientArea(HWND hwnd, int AccumulativeToolbarHeight, RECT ClientArea)
  39. {
  40.  
  41.   AdjustWindowRectEx(&ClientArea,
  42.                      WS_OVERLAPPED | WS_VISIBLE | WS_CAPTION | WS_SYSMENU,
  43.                      true,
  44.                      NULL);
  45.   SetWindowPos(hwnd,
  46.                NULL,
  47.                0,
  48.                0,
  49.                ClientArea.right,
  50.                ClientArea.bottom + AccumulativeToolbarHeight,
  51.                SWP_NOMOVE|SWP_NOZORDER);
  52. }
  53. //---------------------------- WindowProc ---------------------------------
  54. //
  55. // This is the callback function which handles all the windows messages
  56. //-------------------------------------------------------------------------
  57. LRESULT CALLBACK WindowProc (HWND   hwnd,
  58.                              UINT   msg,
  59.                              WPARAM wParam,
  60.                              LPARAM lParam)
  61. {
  62.  
  63.    //these hold the dimensions of the client window area
  64.  static int cxClient, cyClient; 
  65.  //used to create the back buffer
  66.    static HDC hdcBackBuffer;
  67.    static HBITMAP hBitmap = NULL;
  68.    static HBITMAP hOldBitmap = NULL;
  69.    static int ToolBarHeight;
  70.    //to grab filenames
  71.    static TCHAR   szFileName[MAX_PATH],
  72.                   szTitleName[MAX_PATH];
  73.    static RECT rectClientWindow;
  74.    static int CurrentSearchButton = 0;
  75.     switch (msg)
  76.     {
  77. //A WM_CREATE msg is sent when your application window is first
  78. //created
  79.     case WM_CREATE:
  80.       { 
  81.          //seed random number generator
  82.          srand((unsigned) time(NULL));   
  83.          
  84.          //---------------create a surface to render to(backbuffer)
  85.          //create a memory device context
  86.          hdcBackBuffer = CreateCompatibleDC(NULL);
  87.          //get the DC for the front buffer
  88.          HDC hdc = GetDC(hwnd);
  89.          hBitmap = CreateCompatibleBitmap(hdc,
  90.                                           cxClient,
  91.                                           cyClient);
  92.   
  93.          //select the bitmap into the memory device context
  94.    hOldBitmap = (HBITMAP)SelectObject(hdcBackBuffer, hBitmap);
  95.          //don't forget to release the DC
  96.          ReleaseDC(hwnd, hdc);  
  97.          
  98.          //create the controller
  99.          g_Pathfinder = new Pathfinder();
  100.          CheckMenuItemAppropriately(hwnd, IDM_VIEW_TILES, g_Pathfinder->isShowTilesOn());
  101.          CheckMenuItemAppropriately(hwnd, IDM_VIEW_GRAPH, g_Pathfinder->isShowGraphOn());
  102.       }
  103.       break;
  104.       case UM_TOOLBAR_HAS_BEEN_CREATED:
  105.       {
  106.         
  107.           //get the height of the toolbar
  108.          RECT rectToolbar;
  109.          GetWindowRect(g_hwndToolbar, &rectToolbar);
  110.          ToolBarHeight =  abs(rectToolbar.bottom - rectToolbar.top);
  111.          rectClientWindow.left = 0;
  112.          rectClientWindow.right = ClientWidth;
  113.          rectClientWindow.top = 0;
  114.          rectClientWindow.bottom = ClientHeight + InfoWindowHeight;
  115.         ResizeToCorrectClientArea(hwnd, ToolBarHeight, rectClientWindow);
  116.          
  117.         //let the toolbar know about the resize
  118.         SendMessage(g_hwndToolbar, WM_SIZE, wParam, lParam);
  119.         //this defines the area to be redrawn (to prevent the toolbar flickering)
  120.         GetClientRect(hwnd, &rectClientWindow);
  121.         rectClientWindow.bottom = ClientHeight - ToolBarHeight - 1;
  122.          //create a memory device context
  123.          hdcBackBuffer = CreateCompatibleDC(NULL);
  124.          //get the DC for the front buffer
  125.          HDC hdc = GetDC(hwnd);
  126.          hBitmap = CreateCompatibleBitmap(hdc,
  127.                                           rectClientWindow.right,
  128.                                           rectClientWindow.bottom);
  129.   
  130.          //select the bitmap into the memory device context
  131.    hOldBitmap = (HBITMAP)SelectObject(hdcBackBuffer, hBitmap);
  132.          //don't forget to release the DC
  133.          ReleaseDC(hwnd, hdc);      
  134.       }
  135.       break;
  136.     case WM_KEYUP:
  137.       {
  138.         switch(wParam)
  139.         {
  140.          case VK_ESCAPE:
  141.                      
  142.             SendMessage(hwnd, WM_DESTROY, NULL, NULL); break;
  143.           case 'G':
  144.                      
  145.             g_Pathfinder->ToggleShowGraph(); break;
  146.           case 'T':
  147.                      
  148.             g_Pathfinder->ToggleShowTiles(); break;
  149.         }//end switch
  150.         RedrawWindowRect(hwnd, false, rectClientWindow);
  151.       }
  152.       break;
  153.       
  154.     case WM_LBUTTONDOWN:
  155.     {
  156.       g_Pathfinder->PaintTerrain(MAKEPOINTS(lParam));
  157.       RedrawWindowRect(hwnd, false, rectClientWindow);
  158.      
  159.     }
  160.     
  161.     break;
  162.     case WM_MOUSEMOVE:
  163.     {
  164.       switch(wParam)
  165.       {
  166.       case MK_LBUTTON:
  167.         {
  168.           g_Pathfinder->PaintTerrain(MAKEPOINTS(lParam));
  169.           RedrawWindowRect(hwnd, false, rectClientWindow);
  170.         }
  171.         break;
  172.       }
  173.     }
  174.     case WM_COMMAND:
  175.     {
  176.       switch(wParam)
  177.       {
  178.       case ID_BUTTON_STOP:
  179.         g_Pathfinder->ChangeBrush(Pathfinder::target);
  180.         break;
  181.       case ID_BUTTON_START:
  182.         g_Pathfinder->ChangeBrush(Pathfinder::source);
  183.         break;
  184.       case ID_BUTTON_OBSTACLE:
  185.         g_Pathfinder->ChangeBrush(Pathfinder::obstacle);
  186.         break;
  187.       case ID_BUTTON_WATER:
  188.         g_Pathfinder->ChangeBrush(Pathfinder::water);
  189.         break;
  190.       case ID_BUTTON_MUD:
  191.         g_Pathfinder->ChangeBrush(Pathfinder::mud);
  192.         break;
  193.       case ID_BUTTON_NORMAL:
  194.         g_Pathfinder->ChangeBrush(Pathfinder::normal);
  195.         break;
  196.       case ID_BUTTON_DFS:
  197.         g_Pathfinder->CreatePathDFS(); CurrentSearchButton = ID_BUTTON_DFS; break;
  198.         break;
  199.       case ID_BUTTON_BFS:
  200.         g_Pathfinder->CreatePathBFS(); CurrentSearchButton = ID_BUTTON_BFS; break;
  201.         break;
  202.       case ID_BUTTON_DIJKSTRA:
  203.         g_Pathfinder->CreatePathDijkstra(); CurrentSearchButton = ID_BUTTON_DIJKSTRA; break;
  204.         break;
  205.       case ID_BUTTON_ASTAR:
  206.         g_Pathfinder->CreatePathAStar(); CurrentSearchButton = ID_BUTTON_ASTAR; break;
  207.         break;
  208.       case ID_MENU_LOAD:
  209.           
  210.           FileOpenDlg(hwnd, szFileName, szTitleName, "pathfinder files (*.map)", "map");
  211.           if (strlen(szTitleName) > 0)
  212.           {
  213.             g_Pathfinder->Load(szTitleName);
  214.           }
  215.           //uncheck the current search toolbar button
  216.           SendMessage(g_hwndToolbar,
  217.                      TB_CHECKBUTTON,
  218.                      (WPARAM) CurrentSearchButton,
  219.                      (LPARAM) false);
  220.           break;
  221.       case ID_MENU_SAVEAS:
  222.         FileSaveDlg(hwnd, szFileName, szTitleName, "pathfinder files (*.map)", "map");
  223.         if (strlen(szTitleName) > 0)
  224.         {
  225.           g_Pathfinder->Save(szTitleName);
  226.         }
  227.         
  228.         break;
  229.       case ID_MENU_NEW:
  230.         
  231.          //create the graph
  232.          g_Pathfinder->CreateGraph(NumCellsX, NumCellsY);
  233.           //uncheck the current search toolbar button
  234.           SendMessage(g_hwndToolbar,
  235.                      TB_CHECKBUTTON,
  236.                      (WPARAM) CurrentSearchButton,
  237.                      (LPARAM) false);
  238.          break;
  239.        case IDM_VIEW_GRAPH:
  240.           if (GetMenuState(GetMenu(hwnd), IDM_VIEW_GRAPH, MFS_CHECKED) && MF_CHECKED)
  241.           {
  242.             ChangeMenuState(hwnd, IDM_VIEW_GRAPH, MFS_UNCHECKED);
  243.             g_Pathfinder->SwitchGraphOff();
  244.           }
  245.           else
  246.           {
  247.             ChangeMenuState(hwnd, IDM_VIEW_GRAPH, MFS_CHECKED);
  248.             g_Pathfinder->SwitchGraphOn();
  249.           }
  250.           break;
  251.         case IDM_VIEW_TILES:
  252.           if (GetMenuState(GetMenu(hwnd), IDM_VIEW_TILES, MFS_CHECKED) && MF_CHECKED)
  253.           {
  254.             ChangeMenuState(hwnd, IDM_VIEW_TILES, MFS_UNCHECKED);
  255.             g_Pathfinder->SwitchTilesOff();
  256.           }
  257.           else
  258.           {
  259.             ChangeMenuState(hwnd, IDM_VIEW_TILES, MFS_CHECKED);
  260.             g_Pathfinder->SwitchTilesOn();
  261.           }
  262.           break;
  263.       }//end switch
  264.       RedrawWindowRect(hwnd, false, rectClientWindow);
  265.     }
  266.     
  267.     case WM_PAINT:
  268.       {
  269.          
  270.          PAINTSTRUCT ps;
  271.           
  272.          BeginPaint (hwnd, &ps);
  273.         //fill the backbuffer with white
  274.          BitBlt(hdcBackBuffer,
  275.                 0,
  276.                 0,
  277.                 cxClient,
  278.                 cyClient,
  279.                 NULL,
  280.                 NULL,
  281.                 NULL,
  282.                 WHITENESS);
  283.           
  284.         gdi->StartDrawing(hdcBackBuffer);
  285.         g_Pathfinder->Render();
  286.         gdi->StopDrawing(hdcBackBuffer);
  287.          //now blit backbuffer to front
  288.    BitBlt(ps.hdc, 0, 0, cxClient, cyClient, hdcBackBuffer, 0, 0, SRCCOPY); 
  289.           
  290.          EndPaint (hwnd, &ps);
  291.       }
  292.       break;
  293. case WM_SIZE:
  294.   {
  295.   cxClient = LOWORD(lParam);
  296.   cyClient = HIWORD(lParam);
  297.         //now to resize the backbuffer accordingly. First select
  298.         //the old bitmap back into the DC
  299.   SelectObject(hdcBackBuffer, hOldBitmap);
  300.         //don't forget to do this or you will get resource leaks
  301.         DeleteObject(hBitmap); 
  302.   //get the DC for the application
  303.         HDC hdc = GetDC(hwnd);
  304.   //create another bitmap of the same size and mode
  305.         //as the application
  306.        hBitmap = CreateCompatibleBitmap(hdc,
  307.                                         rectClientWindow.right,
  308.                                         rectClientWindow.bottom);
  309.   ReleaseDC(hwnd, hdc);
  310.   
  311.   //select the new bitmap into the DC
  312.         SelectObject(hdcBackBuffer, hBitmap);
  313.       }
  314.       break;
  315.           
  316.  case WM_DESTROY:
  317.  {
  318.          //clean up our backbuffer objects
  319.          SelectObject(hdcBackBuffer, hOldBitmap);
  320.          DeleteDC(hdcBackBuffer);
  321.          DeleteObject(hBitmap); 
  322.          DeleteObject(hOldBitmap);
  323.          
  324.          // kill the application, this sends a WM_QUIT message  
  325.  PostQuitMessage (0);
  326.  }
  327.        break;
  328.      }//end switch
  329.      //this is where all the messages not specifically handled by our 
  330.  //winproc are sent to be processed
  331.  return DefWindowProc (hwnd, msg, wParam, lParam);
  332. }
  333. //----------------------------- CreateToolBar ----------------------------
  334. //------------------------------------------------------------------------
  335. HWND CreateToolBar(HWND hwndParent, HINSTANCE hinstMain)
  336. {
  337.   const int NumButtons = 11;
  338.   
  339.   //load in the common ctrls from the dll
  340.   INITCOMMONCONTROLSEX cc;
  341.   cc.dwSize = sizeof(INITCOMMONCONTROLSEX);
  342.   cc.dwICC = ICC_BAR_CLASSES;
  343.   if (!InitCommonControlsEx(&cc))
  344.   {
  345.     MessageBox(NULL, "Failed to load common ctrls!", "Error!", MB_OK);
  346.     return 0;
  347.   }
  348.     
  349.   //create the toolbar
  350.   HWND hwndToolBar = CreateWindowEx(NULL,                
  351.                              TOOLBARCLASSNAME,   
  352.                              (LPSTR) NULL,           
  353.                              WS_CHILD | WS_VISIBLE | CCS_BOTTOM,  
  354.                              0,
  355.                              0,                    
  356.                              0,           
  357.                              0,          
  358.                              hwndParent,                 
  359.                              (HMENU) IDR_TOOLBAR1,                 
  360.                              hinstMain,            
  361.                              NULL);               
  362.   //make sure the window creation has gone OK
  363.   if(!hwndToolBar)
  364.   {
  365.     MessageBox(NULL, "CreateWindowEx Failed!", "Error!", 0);
  366.   }
  367.   //let the toolbar know the size of the buttons to be added
  368.   SendMessage(hwndToolBar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
  369.   //add bitmaps to the buttons
  370.   TBADDBITMAP tb;
  371.   tb.hInst = NULL;
  372.   tb.nID = (UINT_PTR)LoadBitmap((HINSTANCE)GetWindowLong(hwndParent, GWL_HINSTANCE),MAKEINTRESOURCE(IDR_TOOLBAR1));
  373.   int idx = SendMessage (hwndToolBar, TB_ADDBITMAP, NumButtons, (LPARAM)&tb);
  374.   //create the buttons
  375.   TBBUTTON button[NumButtons];
  376.   button[0].iBitmap   = 0;
  377.   button[0].idCommand = ID_BUTTON_STOP;
  378.   button[0].fsState   = TBSTATE_ENABLED;
  379.   button[0].fsStyle   = TBSTYLE_CHECKGROUP;
  380.   button[0].dwData    = NULL;
  381.   button[0].iString   = NULL;
  382.   button[1].iBitmap   = 1;
  383.   button[1].idCommand = ID_BUTTON_START;
  384.   button[1].fsState   = TBSTATE_ENABLED;
  385.   button[1].fsStyle   = TBSTYLE_CHECKGROUP;
  386.   button[1].dwData    = NULL;
  387.   button[1].iString   = NULL;
  388.   button[2].iBitmap   = 2;
  389.   button[2].idCommand = ID_BUTTON_OBSTACLE;
  390.   button[2].fsState   = TBSTATE_ENABLED;
  391.   button[2].fsStyle   = TBSTYLE_CHECKGROUP;
  392.   button[2].dwData    = NULL;
  393.   button[2].iString   = NULL;
  394.   button[3].iBitmap   = 3;
  395.   button[3].idCommand = ID_BUTTON_MUD;
  396.   button[3].fsState   = TBSTATE_ENABLED;
  397.   button[3].fsStyle   = TBSTYLE_CHECKGROUP;
  398.   button[3].dwData    = NULL;
  399.   button[3].iString   = NULL;
  400.   button[4].iBitmap   = 4;
  401.   button[4].idCommand = ID_BUTTON_WATER;
  402.   button[4].fsState   = TBSTATE_ENABLED;
  403.   button[4].fsStyle   = TBSTYLE_CHECKGROUP;
  404.   button[4].dwData    = NULL;
  405.   button[4].iString   = NULL;
  406.   button[5].iBitmap   = 5;
  407.   button[5].idCommand = ID_BUTTON_NORMAL;
  408.   button[5].fsState   = TBSTATE_ENABLED;
  409.   button[5].fsStyle   = TBSTYLE_CHECKGROUP;
  410.   button[5].dwData    = NULL;
  411.   button[5].iString   = NULL;
  412.   //this creates a separater
  413.   button[6].iBitmap   = 265;
  414.   button[6].idCommand = 0;
  415.   button[6].fsState   = NULL;
  416.   button[6].fsStyle   = TBSTYLE_SEP;
  417.   button[6].dwData    = NULL;
  418.   button[6].iString   = NULL;
  419.   button[7].iBitmap   = 6;
  420.   button[7].idCommand = ID_BUTTON_DFS;
  421.   button[7].fsState   = TBSTATE_ENABLED;
  422.   button[7].fsStyle   = TBSTYLE_CHECKGROUP;
  423.   button[7].dwData    = NULL;
  424.   button[7].iString   = NULL;
  425.   button[8].iBitmap   = 7;
  426.   button[8].idCommand = ID_BUTTON_BFS;
  427.   button[8].fsState   = TBSTATE_ENABLED;
  428.   button[8].fsStyle   = TBSTYLE_CHECKGROUP;
  429.   button[8].dwData    = NULL;
  430.   button[8].iString   = NULL;
  431.   button[9].iBitmap   = 8;
  432.   button[9].idCommand = ID_BUTTON_DIJKSTRA;
  433.   button[9].fsState   = TBSTATE_ENABLED;
  434.   button[9].fsStyle   = TBSTYLE_CHECKGROUP;
  435.   button[9].dwData    = NULL;
  436.   button[9].iString   = NULL;
  437.   button[10].iBitmap   = 9;
  438.   button[10].idCommand = ID_BUTTON_ASTAR;
  439.   button[10].fsState   = TBSTATE_ENABLED;
  440.   button[10].fsStyle   = TBSTYLE_CHECKGROUP;
  441.   button[10].dwData    = NULL;
  442.   button[10].iString   = NULL;
  443.   //add the buttons to the toolbar
  444.   SendMessage(hwndToolBar, TB_ADDBUTTONS, (WPARAM)NumButtons, (LPARAM)(LPTBBUTTON)&button);
  445.   return hwndToolBar;
  446. }
  447. //-------------------------------- WinMain -------------------------------
  448. //
  449. // The entry point of the windows program
  450. //------------------------------------------------------------------------
  451. int WINAPI WinMain (HINSTANCE hInstance,
  452.                     HINSTANCE hPrevInstance,
  453.                     LPSTR     szCmdLine, 
  454.                     int       iCmdShow)
  455. {
  456.      //handle to our window
  457.  HWND hWnd;
  458.     
  459.  //our window class structure
  460.  WNDCLASSEX     winclass;
  461.  
  462.      // first fill in the window class stucture
  463.    winclass.cbSize        = sizeof(WNDCLASSEX);
  464.    winclass.style         = CS_HREDRAW | CS_VREDRAW;
  465.      winclass.lpfnWndProc   = WindowProc;
  466.      winclass.cbClsExtra    = 0;
  467.      winclass.cbWndExtra    = 0;
  468.      winclass.hInstance     = hInstance;
  469.      winclass.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
  470.      winclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
  471.      winclass.hbrBackground = NULL;
  472.      winclass.lpszMenuName  = MAKEINTRESOURCE(IDR_MENU1);
  473.      winclass.lpszClassName = g_szWindowClassName;
  474.    winclass.hIconSm       = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
  475.  //register the window class
  476. if (!RegisterClassEx(&winclass))
  477. {
  478. MessageBox(NULL, "Registration Failed!", "Error", 0);
  479. //exit the application
  480. return 0;
  481. }
  482.  //create the window    
  483.      hWnd = CreateWindowEx (NULL,                 // extended style
  484.                             g_szWindowClassName,  // window class name
  485.                             g_szApplicationName,  // window caption
  486.                             WS_OVERLAPPED | WS_VISIBLE | WS_CAPTION | WS_SYSMENU,  // window style
  487.                             GetSystemMetrics(SM_CXSCREEN)/2 - WindowWidth/2,
  488.                             GetSystemMetrics(SM_CYSCREEN)/2 - WindowHeight/2,                    
  489.                             WindowWidth,           // initial x size
  490.                             WindowHeight,          // initial y size
  491.                             NULL,                 // parent window handle
  492.                             NULL,                 // window menu handle
  493.                             hInstance,            // program instance handle
  494.                             NULL);                // creation parameters
  495.   //make sure the window creation has gone OK
  496.   if(!hWnd)
  497.   {
  498.     MessageBox(NULL, "CreateWindowEx Failed!", "Error!", 0);
  499.   }
  500.   //create the toolbar
  501.   g_hwndToolbar = CreateToolBar(hWnd, hInstance);
  502.   SendMessage(hWnd, UM_TOOLBAR_HAS_BEEN_CREATED, NULL, NULL);
  503.   //create the graph
  504.   g_Pathfinder->CreateGraph(NumCellsX, NumCellsY);
  505.      
  506.   //enter the message loop
  507.   //this will hold any windows messages
  508.   MSG msg;
  509.      
  510.   //entry point of our message handler
  511. while (GetMessage (&msg, NULL, 0, 0))
  512.   {
  513.      TranslateMessage (&msg);
  514.      DispatchMessage (&msg);
  515.   }
  516.   delete g_Pathfinder;
  517.   UnregisterClass( g_szWindowClassName, winclass.hInstance );
  518.   return msg.wParam;
  519. }