home *** CD-ROM | disk | FTP | other *** search
/ Beginning C++ Through Gam…rogramming (2nd Edition) / BCGP2E.ISO / bloodshed / devcpp-4.9.9.2_setup.exe / Examples / MDIApp / mdi_unit.c < prev    next >
C/C++ Source or Header  |  2002-06-03  |  17KB  |  507 lines

  1. #include <windows.h>
  2. #include <commctrl.h>
  3.  
  4. #include "mdi_unit.h"
  5.  
  6. #define ID_STATUSBAR       4997
  7. #define ID_TOOLBAR         4998
  8.  
  9. #define ID_MDI_CLIENT      4999
  10. #define ID_MDI_FIRSTCHILD  50000
  11.  
  12. #define IDC_CHILD_EDIT      2000
  13.  
  14. LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam);
  15. LRESULT CALLBACK MDIChildWndProc(HWND hwnd, UINT Message, WPARAM wParam,
  16.    LPARAM lParam);
  17.  
  18. char g_szAppName[] = "MyMDIWindow";
  19. char g_szChild[] = "MyMDIChild";
  20. HINSTANCE g_hInst;
  21. HWND g_hMDIClient, g_hStatusBar, g_hToolBar;
  22. HWND g_hMainWindow;
  23.  
  24. BOOL LoadFile(HWND hEdit, LPSTR pszFileName)
  25. {
  26.    HANDLE hFile;
  27.    BOOL bSuccess = FALSE;
  28.  
  29.    hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
  30.       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  31.    if(hFile != INVALID_HANDLE_VALUE)
  32.    {
  33.       DWORD dwFileSize;
  34.       dwFileSize = GetFileSize(hFile, NULL);
  35.       if(dwFileSize != 0xFFFFFFFF)
  36.       {
  37.          LPSTR pszFileText;
  38.          pszFileText = LPSTR(GlobalAlloc(GPTR, dwFileSize + 1));
  39.          if(pszFileText != NULL)
  40.          {
  41.             DWORD dwRead;
  42.             if(ReadFile(hFile, pszFileText, dwFileSize, &dwRead, NULL))
  43.             {
  44.                pszFileText[dwFileSize] = 0; // Null terminator
  45.                if(SetWindowText(hEdit, pszFileText))
  46.                   bSuccess = TRUE; // It worked!
  47.             }
  48.             GlobalFree(pszFileText);
  49.          }
  50.       }
  51.       CloseHandle(hFile);
  52.    }
  53.    return bSuccess;
  54. }
  55.  
  56. BOOL SaveFile(HWND hEdit, LPSTR pszFileName)
  57. {
  58.    HANDLE hFile;
  59.    BOOL bSuccess = FALSE;
  60.  
  61.    hFile = CreateFile(pszFileName, GENERIC_WRITE, 0, NULL,
  62.       CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
  63.    if(hFile != INVALID_HANDLE_VALUE)
  64.    {
  65.       DWORD dwTextLength;
  66.       dwTextLength = GetWindowTextLength(hEdit);
  67.       if(dwTextLength > 0)// No need to bother if there's no text.
  68.       {
  69.          LPSTR pszText;
  70.          pszText = LPSTR(GlobalAlloc(GPTR, dwTextLength + 1));
  71.          if(pszText != NULL)
  72.          {
  73.             if(GetWindowText(hEdit, pszText, dwTextLength + 1))
  74.             {
  75.                DWORD dwWritten;
  76.                if(WriteFile(hFile, pszText, dwTextLength, &dwWritten, NULL))
  77.                   bSuccess = TRUE;
  78.             }
  79.             GlobalFree(pszText);
  80.          }
  81.       }
  82.       CloseHandle(hFile);
  83.    }
  84.    return bSuccess;
  85. }
  86.  
  87. BOOL GetFileName(HWND hwnd, LPSTR pszFileName, BOOL bSave)
  88. {
  89.    OPENFILENAME ofn;
  90.  
  91.    ZeroMemory(&ofn, sizeof(ofn));
  92.    pszFileName[0] = 0;
  93.  
  94.    ofn.lStructSize = sizeof(ofn);
  95.    ofn.hwndOwner = hwnd;
  96.    ofn.lpstrFilter = "Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0\0";
  97.    ofn.lpstrFile = pszFileName;
  98.    ofn.nMaxFile = MAX_PATH;
  99.    ofn.lpstrDefExt = "txt";
  100.  
  101.    if(bSave)
  102.    {
  103.       ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY |
  104.          OFN_OVERWRITEPROMPT;
  105.       if(!GetSaveFileName(&ofn))
  106.          return FALSE;
  107.    }
  108.    else
  109.    {
  110.       ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
  111.       if(!GetOpenFileName(&ofn))
  112.          return FALSE;
  113.    }
  114.    return TRUE;
  115. }
  116.  
  117. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  118.    LPSTR lpszCmdParam, int nCmdShow)
  119. {
  120.    MSG  Msg;
  121.    WNDCLASSEX WndClassEx;
  122.  
  123.    InitCommonControls();
  124.  
  125.    g_hInst = hInstance;
  126.  
  127.    WndClassEx.cbSize          = sizeof(WNDCLASSEX);
  128.    WndClassEx.style           = CS_HREDRAW | CS_VREDRAW;
  129.    WndClassEx.lpfnWndProc     = WndProc;
  130.    WndClassEx.cbClsExtra      = 0;
  131.    WndClassEx.cbWndExtra      = 0;
  132.    WndClassEx.hInstance       = hInstance;
  133.    WndClassEx.hIcon           = LoadIcon(NULL, IDI_APPLICATION);
  134.    WndClassEx.hCursor         = LoadCursor(NULL, IDC_ARROW);
  135.    WndClassEx.hbrBackground   = (HBRUSH)(COLOR_3DSHADOW+1);
  136.    WndClassEx.lpszMenuName       = "MAIN";
  137.    WndClassEx.lpszClassName   = g_szAppName;
  138.    WndClassEx.hIconSm           = LoadIcon(NULL, IDI_APPLICATION);
  139.  
  140.    if(!RegisterClassEx(&WndClassEx))
  141.    {
  142.       MessageBox(0, "Could Not Register Window", "Oh Oh...",
  143.          MB_ICONEXCLAMATION | MB_OK);
  144.       return -1;
  145.    }
  146.  
  147.    WndClassEx.lpfnWndProc     = MDIChildWndProc;
  148.    WndClassEx.lpszMenuName       = NULL;
  149.    WndClassEx.lpszClassName   = g_szChild;
  150.    WndClassEx.hbrBackground   = (HBRUSH)(COLOR_3DFACE+1);
  151.  
  152.    if(!RegisterClassEx(&WndClassEx))
  153.    {
  154.       MessageBox(0, "Could Not Register Child Window", "Oh Oh...",
  155.          MB_ICONEXCLAMATION | MB_OK);
  156.       return -1;
  157.    }
  158.  
  159.     g_hMainWindow = CreateWindowEx(WS_EX_APPWINDOW, g_szAppName,
  160.       "MDI File Editor", WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
  161.       CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  162.       0, 0, hInstance, NULL);
  163.  
  164.    if (g_hMainWindow == NULL){
  165.       MessageBox(0, "No Window", "Oh Oh...", MB_ICONEXCLAMATION | MB_OK);
  166.       return -1;
  167.    }
  168.  
  169.    ShowWindow(g_hMainWindow, nCmdShow);
  170.    UpdateWindow(g_hMainWindow);
  171.  
  172.    while(GetMessage(&Msg, NULL, 0, 0))
  173.    {
  174.       if (!TranslateMDISysAccel(g_hMDIClient, &Msg))
  175.       {
  176.          TranslateMessage(&Msg);
  177.          DispatchMessage(&Msg);
  178.       }
  179.    }
  180.    return Msg.wParam;
  181. }
  182.  
  183.  
  184. LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
  185. {
  186.    switch(Message)
  187.    {
  188.       case WM_CREATE:
  189.       {
  190.          CLIENTCREATESTRUCT ccs;
  191.          int iStatusWidths[] = {200, 300, -1};
  192.          TBADDBITMAP tbab;
  193.          TBBUTTON tbb[9];
  194.  
  195.          // Find window menu where children will be listed
  196.          ccs.hWindowMenu  = GetSubMenu(GetMenu(hwnd), 2);
  197.          ccs.idFirstChild = ID_MDI_FIRSTCHILD;
  198.          g_hMDIClient = CreateWindowEx(WS_EX_CLIENTEDGE, "mdiclient", NULL,
  199.             WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL,
  200.             CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  201.             hwnd, (HMENU)ID_MDI_CLIENT, g_hInst, (LPVOID)&ccs);
  202.          ShowWindow(g_hMDIClient, SW_SHOW);
  203.  
  204.          g_hStatusBar = CreateWindowEx(0, STATUSCLASSNAME, NULL,
  205.             WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0,
  206.             hwnd, (HMENU)ID_STATUSBAR, g_hInst, NULL);
  207.          SendMessage(g_hStatusBar, SB_SETPARTS, 3, (LPARAM)iStatusWidths);
  208.          SendMessage(g_hStatusBar, SB_SETTEXT, 2, (LPARAM)"Toolbar & Statusbar Example");
  209.  
  210.          g_hToolBar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL,
  211.             WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
  212.             hwnd, (HMENU)ID_TOOLBAR, g_hInst, NULL);
  213.  
  214.          // Send the TB_BUTTONSTRUCTSIZE message, which is required for
  215.          // backward compatibility.
  216.          SendMessage(g_hToolBar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
  217.  
  218.          tbab.hInst = HINST_COMMCTRL;
  219.          tbab.nID = IDB_STD_SMALL_COLOR;
  220.          SendMessage(g_hToolBar, TB_ADDBITMAP, 0, (LPARAM)&tbab);
  221.  
  222.          ZeroMemory(tbb, sizeof(tbb));
  223.  
  224.          tbb[0].iBitmap = STD_FILENEW;
  225.          tbb[0].fsState = TBSTATE_ENABLED;
  226.          tbb[0].fsStyle = TBSTYLE_BUTTON;
  227.          tbb[0].idCommand = CM_FILE_NEW;
  228.  
  229.          tbb[1].iBitmap = STD_FILEOPEN;
  230.          tbb[1].fsState = TBSTATE_ENABLED;
  231.          tbb[1].fsStyle = TBSTYLE_BUTTON;
  232.          tbb[1].idCommand = CM_FILE_OPEN;
  233.  
  234.          tbb[2].iBitmap = STD_FILESAVE;
  235.          tbb[2].fsStyle = TBSTYLE_BUTTON;
  236.          tbb[2].idCommand = CM_FILE_SAVE;
  237.  
  238.          tbb[3].fsStyle = TBSTYLE_SEP;
  239.  
  240.          tbb[4].iBitmap = STD_CUT;
  241.          tbb[4].fsStyle = TBSTYLE_BUTTON;
  242.          tbb[4].idCommand = CM_EDIT_CUT;
  243.  
  244.          tbb[5].iBitmap = STD_COPY;
  245.          tbb[5].fsStyle = TBSTYLE_BUTTON;
  246.          tbb[5].idCommand = CM_EDIT_COPY;
  247.  
  248.          tbb[6].iBitmap = STD_PASTE;
  249.          tbb[6].fsStyle = TBSTYLE_BUTTON;
  250.          tbb[6].idCommand = CM_EDIT_PASTE;
  251.  
  252.          tbb[7].fsStyle = TBSTYLE_SEP;
  253.  
  254.          tbb[8].iBitmap = STD_UNDO;
  255.          tbb[8].fsStyle = TBSTYLE_BUTTON;
  256.          tbb[8].idCommand = CM_EDIT_UNDO;
  257.  
  258.          SendMessage(g_hToolBar, TB_ADDBUTTONS, 9, (LPARAM)&tbb);
  259.  
  260.          return 0;
  261.       }
  262.       case WM_COMMAND:
  263.       {
  264.          switch(LOWORD(wParam))
  265.          {
  266.             case CM_FILE_EXIT:
  267.                PostMessage(hwnd, WM_CLOSE, 0, 0);
  268.             break;
  269.             case CM_FILE_NEW:
  270.             {
  271.                MDICREATESTRUCT mcs;
  272.                HWND hChild;
  273.  
  274.                mcs.szTitle = "[Untitled]";
  275.                mcs.szClass = g_szChild;
  276.                mcs.hOwner  = g_hInst;
  277.                mcs.x = mcs.cx = CW_USEDEFAULT;
  278.                mcs.y = mcs.cy = CW_USEDEFAULT;
  279.                mcs.style = MDIS_ALLCHILDSTYLES;
  280.  
  281.                hChild = (HWND)SendMessage(g_hMDIClient, WM_MDICREATE,
  282.                   0, (LONG)&mcs);
  283.                if(!hChild)
  284.                {
  285.                   MessageBox(hwnd, "MDI Child creation failed.", "Oh Oh...",
  286.                      MB_ICONEXCLAMATION | MB_OK);
  287.                }
  288.             }
  289.             break;
  290.             case CM_FILE_OPEN:
  291.             {
  292.                MDICREATESTRUCT mcs;
  293.                HWND hChild;
  294.                char szFileName[MAX_PATH];
  295.  
  296.                if(!GetFileName(hwnd, szFileName, FALSE))
  297.                   break;
  298.  
  299.                mcs.szTitle = szFileName;
  300.                mcs.szClass = g_szChild;
  301.                mcs.hOwner  = g_hInst;
  302.                mcs.x = mcs.cx = CW_USEDEFAULT;
  303.                mcs.y = mcs.cy = CW_USEDEFAULT;
  304.                mcs.style = MDIS_ALLCHILDSTYLES;
  305.  
  306.                hChild = (HWND)SendMessage(g_hMDIClient, WM_MDICREATE,
  307.                   0, (LONG)&mcs);
  308.  
  309.                if(!hChild)
  310.                {
  311.                   MessageBox(hwnd, "MDI Child creation failed.", "Oh Oh...",
  312.                      MB_ICONEXCLAMATION | MB_OK);
  313.                }
  314.             }
  315.             break;
  316.             case CM_WINDOW_TILEHORZ:
  317.                PostMessage(g_hMDIClient, WM_MDITILE, MDITILE_HORIZONTAL, 0);
  318.             break;
  319.             case CM_WINDOW_TILEVERT:
  320.                PostMessage(g_hMDIClient, WM_MDITILE, MDITILE_VERTICAL, 0);
  321.             break;
  322.             case CM_WINDOW_CASCADE:
  323.                PostMessage(g_hMDIClient, WM_MDICASCADE, 0, 0);
  324.             break;
  325.             case CM_WINDOW_ARRANGE:
  326.                PostMessage(g_hMDIClient, WM_MDIICONARRANGE, 0, 0);
  327.             break;
  328.             default:
  329.             {
  330.                if(LOWORD(wParam) >= ID_MDI_FIRSTCHILD){
  331.                   DefFrameProc(hwnd, g_hMDIClient, Message, wParam, lParam);
  332.                }
  333.                else {
  334.                   HWND hChild;
  335.                   hChild = (HWND)SendMessage(g_hMDIClient, WM_MDIGETACTIVE,0,0);
  336.                   if(hChild){
  337.                      SendMessage(hChild, WM_COMMAND, wParam, lParam);
  338.                   }
  339.                }
  340.             }
  341.          }
  342.       }
  343.       break;
  344.       case WM_SIZE:
  345.       {
  346.          RECT rectClient, rectStatus, rectTool;
  347.          UINT uToolHeight, uStatusHeight, uClientAlreaHeight;
  348.  
  349.          SendMessage(g_hToolBar, TB_AUTOSIZE, 0, 0);
  350.          SendMessage(g_hStatusBar, WM_SIZE, 0, 0);
  351.  
  352.          GetClientRect(hwnd, &rectClient);
  353.          GetWindowRect(g_hStatusBar, &rectStatus);
  354.          GetWindowRect(g_hToolBar, &rectTool);
  355.  
  356.          uToolHeight = rectTool.bottom - rectTool.top;
  357.          uStatusHeight = rectStatus.bottom - rectStatus.top;
  358.          uClientAlreaHeight = rectClient.bottom;
  359.  
  360.          MoveWindow(g_hMDIClient, 0, uToolHeight, rectClient.right, uClientAlreaHeight - uStatusHeight - uToolHeight, TRUE);
  361.       }
  362.       break;
  363.       case WM_CLOSE:
  364.          DestroyWindow(hwnd);
  365.       break;
  366.       case WM_DESTROY:
  367.          PostQuitMessage(0);
  368.       break;
  369.       default:
  370.          return DefFrameProc(hwnd, g_hMDIClient, Message, wParam, lParam);
  371.    }
  372.    return 0;
  373. }
  374.  
  375. LRESULT CALLBACK MDIChildWndProc(HWND hwnd, UINT Message, WPARAM wParam,
  376.    LPARAM lParam)
  377. {
  378.    switch(Message)
  379.    {
  380.       case WM_CREATE:
  381.       {
  382.          char szFileName[MAX_PATH];
  383.          HWND hEdit;
  384.  
  385.          hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "",
  386.             WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | ES_MULTILINE |
  387.                ES_WANTRETURN,
  388.             CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  389.             hwnd, (HMENU)IDC_CHILD_EDIT, g_hInst, NULL);
  390.  
  391.          SendMessage(hEdit, WM_SETFONT,
  392.             (WPARAM)GetStockObject(DEFAULT_GUI_FONT), MAKELPARAM(TRUE, 0));
  393.  
  394.          GetWindowText(hwnd, szFileName, MAX_PATH);
  395.          if(*szFileName != '[')
  396.          {
  397.             if(!LoadFile(hEdit, szFileName))
  398.             {
  399.                MessageBox(hwnd, "Couldn't Load File.", "Error.",
  400.                   MB_OK | MB_ICONEXCLAMATION);
  401.                return -1; //cancel window creation
  402.             }
  403.          }
  404.       }
  405.       break;
  406.       case WM_SIZE:
  407.          if(wParam != SIZE_MINIMIZED)
  408.             MoveWindow(GetDlgItem(hwnd, IDC_CHILD_EDIT), 0, 0, LOWORD(lParam),
  409.                HIWORD(lParam), TRUE);
  410.       break;
  411.       case WM_MDIACTIVATE:
  412.       {
  413.          HMENU hMenu, hFileMenu;
  414.          BOOL EnableFlag;
  415.          char szFileName[MAX_PATH];
  416.  
  417.          hMenu = GetMenu(g_hMainWindow);
  418.          if(hwnd == (HWND)lParam){      //being activated
  419.             EnableFlag = TRUE;
  420.          }
  421.          else{
  422.             EnableFlag = FALSE;    //being de-activated
  423.          }
  424.          EnableMenuItem(hMenu, 1, MF_BYPOSITION | (EnableFlag ? MF_ENABLED : MF_GRAYED));
  425.          EnableMenuItem(hMenu, 2, MF_BYPOSITION | (EnableFlag ? MF_ENABLED : MF_GRAYED));
  426.  
  427.          hFileMenu = GetSubMenu(hMenu, 0);
  428.          EnableMenuItem(hFileMenu, CM_FILE_SAVE, MF_BYCOMMAND | (EnableFlag ? MF_ENABLED : MF_GRAYED));
  429.          EnableMenuItem(hFileMenu, CM_FILE_SAVEAS, MF_BYCOMMAND | (EnableFlag ? MF_ENABLED : MF_GRAYED));
  430.  
  431.          DrawMenuBar(g_hMainWindow);
  432.  
  433.          SendMessage(g_hToolBar, TB_ENABLEBUTTON, CM_FILE_SAVE, MAKELONG(EnableFlag, 0));
  434.          SendMessage(g_hToolBar, TB_ENABLEBUTTON, CM_EDIT_UNDO, MAKELONG(EnableFlag, 0));
  435.          SendMessage(g_hToolBar, TB_ENABLEBUTTON, CM_EDIT_CUT, MAKELONG(EnableFlag, 0));
  436.          SendMessage(g_hToolBar, TB_ENABLEBUTTON, CM_EDIT_COPY, MAKELONG(EnableFlag, 0));
  437.          SendMessage(g_hToolBar, TB_ENABLEBUTTON, CM_EDIT_PASTE, MAKELONG(EnableFlag, 0));
  438.  
  439.          GetWindowText(hwnd, szFileName, MAX_PATH);
  440.          SendMessage(g_hStatusBar, SB_SETTEXT, 0, (LPARAM)(EnableFlag ? szFileName : ""));
  441.       }
  442.       break;
  443.       case WM_SETFOCUS:
  444.          SetFocus(GetDlgItem(hwnd, IDC_CHILD_EDIT));
  445.       break;
  446.       case WM_COMMAND:
  447.          switch(LOWORD(wParam))
  448.          {
  449.             case CM_FILE_SAVE:
  450.             {
  451.                char szFileName[MAX_PATH];
  452.  
  453.                GetWindowText(hwnd, szFileName, MAX_PATH);
  454.                if(*szFileName != '[')
  455.                {
  456.                   if(!SaveFile(GetDlgItem(hwnd, IDC_CHILD_EDIT), szFileName))
  457.                   {
  458.                      MessageBox(hwnd, "Couldn't Save File.", "Error.",
  459.                         MB_OK | MB_ICONEXCLAMATION);
  460.                      return 0;
  461.                   }
  462.                }
  463.                else
  464.                {
  465.                   PostMessage(hwnd, WM_COMMAND,
  466.                      MAKEWPARAM(CM_FILE_SAVEAS, 0), 0);
  467.                }
  468.             }
  469.             return 0;
  470.             case CM_FILE_SAVEAS:
  471.             {
  472.                char szFileName[MAX_PATH];
  473.  
  474.                if(GetFileName(hwnd, szFileName, TRUE))
  475.                {
  476.                   if(!SaveFile(GetDlgItem(hwnd, IDC_CHILD_EDIT), szFileName))
  477.                   {
  478.                      MessageBox(hwnd, "Couldn't Save File.", "Error.",
  479.                         MB_OK | MB_ICONEXCLAMATION);
  480.                      return 0;
  481.                   }
  482.                   else
  483.                   {
  484.                      SetWindowText(hwnd, szFileName);
  485.                   }
  486.                }
  487.             }
  488.             return 0;
  489.             case CM_EDIT_UNDO:
  490.                SendDlgItemMessage(hwnd, IDC_CHILD_EDIT, EM_UNDO, 0, 0);
  491.             break;
  492.             case CM_EDIT_CUT:
  493.                SendDlgItemMessage(hwnd, IDC_CHILD_EDIT, WM_CUT, 0, 0);
  494.             break;
  495.             case CM_EDIT_COPY:
  496.                SendDlgItemMessage(hwnd, IDC_CHILD_EDIT, WM_COPY, 0, 0);
  497.             break;
  498.             case CM_EDIT_PASTE:
  499.                SendDlgItemMessage(hwnd, IDC_CHILD_EDIT, WM_PASTE, 0, 0);
  500.             break;
  501.          }
  502.       return 0;
  503.    }
  504.    return DefMDIChildProc(hwnd, Message, wParam, lParam);
  505. }
  506.  
  507.