diff --git a/reactos/apps/tests/Makefile b/reactos/apps/tests/Makefile index a0d845d39e8..0dffe3650c2 100644 --- a/reactos/apps/tests/Makefile +++ b/reactos/apps/tests/Makefile @@ -9,7 +9,7 @@ include $(PATH_TO_TOP)/rules.mak # test_old tests TEST_APPS = accelerator SampleWindow alive apc args atomtest bench bitblt button \ button2 capclock carets cliarea combo consume copymove count dibtest \ -dump_shared_data edit enumwnd event file global_mem hello \ +dump_shared_data edit enumwnd event file global_mem hello mdi \ hivetest hotkey icontest isotest lineclip linetest lock lpc messagebox \ mktime mstest multiwin mutex nptest patblt pipe primitives pteb regtest \ sectest sertest shaptest shm statst statst2 stretchblt suspend \ diff --git a/reactos/apps/tests/mdi/.cvsignore b/reactos/apps/tests/mdi/.cvsignore new file mode 100644 index 00000000000..d63774a7353 --- /dev/null +++ b/reactos/apps/tests/mdi/.cvsignore @@ -0,0 +1,6 @@ +*.o +*.d +*.exe +*.coff +*.sym +*.map diff --git a/reactos/apps/tests/mdi/makefile b/reactos/apps/tests/mdi/makefile new file mode 100644 index 00000000000..72b61b949c9 --- /dev/null +++ b/reactos/apps/tests/mdi/makefile @@ -0,0 +1,25 @@ +# $Id: makefile,v 1.1 2003/12/10 19:18:06 weiden Exp $ + +PATH_TO_TOP = ../../.. + +TARGET_NORC = no + +TARGET_TYPE = program + +TARGET_APPTYPE = windows + +TARGET_NAME = mdi + +TARGET_SDKLIBS = kernel32.a gdi32.a ntdll.a comctl32.a + +TARGET_GCCLIBS = comdlg32 + +TARGET_OBJECTS = $(TARGET_NAME).o + +TARGET_CFLAGS = -Wall -Werror + +include $(PATH_TO_TOP)/rules.mak + +include $(TOOLS_PATH)/helper.mk + +# EOF diff --git a/reactos/apps/tests/mdi/mdi.c b/reactos/apps/tests/mdi/mdi.c new file mode 100644 index 00000000000..4694758be4a --- /dev/null +++ b/reactos/apps/tests/mdi/mdi.c @@ -0,0 +1,521 @@ +/* + Thanks to theForger from winprog.org +*/ +#include +#include +#include "resource.h" + +const char g_szClassName[] = "myWindowClass"; +const char g_szChildClassName[] = "myMDIChildWindowClass"; + +#define IDC_MAIN_MDI 101 +#define IDC_MAIN_TOOL 102 +#define IDC_MAIN_STATUS 103 + +#define IDC_CHILD_EDIT 101 + +#define ID_MDI_FIRSTCHILD 50000 + +HWND g_hMDIClient = NULL; +HWND g_hMainWindow = NULL; + +BOOL LoadTextFileToEdit(HWND hEdit, LPCTSTR pszFileName) +{ + HANDLE hFile; + BOOL bSuccess = FALSE; + + hFile = CreateFile(pszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, 0, NULL); + if(hFile != INVALID_HANDLE_VALUE) + { + DWORD dwFileSize; + + dwFileSize = GetFileSize(hFile, NULL); + if(dwFileSize != 0xFFFFFFFF) + { + LPSTR pszFileText; + + pszFileText = GlobalAlloc(GPTR, dwFileSize + 1); + if(pszFileText != NULL) + { + DWORD dwRead; + + if(ReadFile(hFile, pszFileText, dwFileSize, &dwRead, NULL)) + { + pszFileText[dwFileSize] = 0; // Add null terminator + if(SetWindowText(hEdit, pszFileText)) + bSuccess = TRUE; // It worked! + } + GlobalFree(pszFileText); + } + } + CloseHandle(hFile); + } + return bSuccess; +} + +BOOL SaveTextFileFromEdit(HWND hEdit, LPCTSTR pszFileName) +{ + HANDLE hFile; + BOOL bSuccess = FALSE; + + hFile = CreateFile(pszFileName, GENERIC_WRITE, 0, NULL, + CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if(hFile != INVALID_HANDLE_VALUE) + { + DWORD dwTextLength; + + dwTextLength = GetWindowTextLength(hEdit); + // No need to bother if there's no text. + if(dwTextLength > 0) + { + LPSTR pszText; + DWORD dwBufferSize = dwTextLength + 1; + + pszText = GlobalAlloc(GPTR, dwBufferSize); + if(pszText != NULL) + { + if(GetWindowText(hEdit, pszText, dwBufferSize)) + { + DWORD dwWritten; + + if(WriteFile(hFile, pszText, dwTextLength, &dwWritten, NULL)) + bSuccess = TRUE; + } + GlobalFree(pszText); + } + } + CloseHandle(hFile); + } + return bSuccess; +} + +void DoFileOpen(HWND hwnd) +{ + OPENFILENAME ofn; + char szFileName[MAX_PATH] = ""; + + ZeroMemory(&ofn, sizeof(ofn)); + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = "Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0"; + ofn.lpstrFile = szFileName; + ofn.nMaxFile = MAX_PATH; + ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; + ofn.lpstrDefExt = "txt"; + + if(GetOpenFileName(&ofn)) + { + HWND hEdit = GetDlgItem(hwnd, IDC_CHILD_EDIT); + if(LoadTextFileToEdit(hEdit, szFileName)) + { + SendDlgItemMessage(g_hMainWindow, IDC_MAIN_STATUS, SB_SETTEXT, 0, (LPARAM)"Opened..."); + SendDlgItemMessage(g_hMainWindow, IDC_MAIN_STATUS, SB_SETTEXT, 1, (LPARAM)szFileName); + + SetWindowText(hwnd, szFileName); + } + } +} + +void DoFileSave(HWND hwnd) +{ + OPENFILENAME ofn; + char szFileName[MAX_PATH] = ""; + + ZeroMemory(&ofn, sizeof(ofn)); + + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = "Text Files (*.txt)\0*.txt\0All Files (*.*)\0*.*\0"; + ofn.lpstrFile = szFileName; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrDefExt = "txt"; + ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT; + + if(GetSaveFileName(&ofn)) + { + HWND hEdit = GetDlgItem(hwnd, IDC_CHILD_EDIT); + if(SaveTextFileFromEdit(hEdit, szFileName)) + { + SendDlgItemMessage(g_hMainWindow, IDC_MAIN_STATUS, SB_SETTEXT, 0, (LPARAM)"Saved..."); + SendDlgItemMessage(g_hMainWindow, IDC_MAIN_STATUS, SB_SETTEXT, 1, (LPARAM)szFileName); + + SetWindowText(hwnd, szFileName); + } + } +} + +HWND CreateNewMDIChild(HWND hMDIClient) +{ + MDICREATESTRUCT mcs; + HWND hChild; + + mcs.szTitle = "[Untitled]"; + mcs.szClass = g_szChildClassName; + mcs.hOwner = GetModuleHandle(NULL); + mcs.x = mcs.cx = CW_USEDEFAULT; + mcs.y = mcs.cy = CW_USEDEFAULT; + mcs.style = MDIS_ALLCHILDSTYLES; + + hChild = (HWND)SendMessage(hMDIClient, WM_MDICREATE, 0, (LONG)&mcs); + if(!hChild) + { + MessageBox(hMDIClient, "MDI Child creation failed.", "Oh Oh...", + MB_ICONEXCLAMATION | MB_OK); + } + return hChild; +} + +LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_CREATE: + { + HWND hTool; + TBBUTTON tbb[3]; + TBADDBITMAP tbab; + + HWND hStatus; + int statwidths[] = {100, -1}; + + CLIENTCREATESTRUCT ccs; + + // Create MDI Client + + // Find window menu where children will be listed + ccs.hWindowMenu = GetSubMenu(GetMenu(hwnd), 2); + ccs.idFirstChild = ID_MDI_FIRSTCHILD; + + g_hMDIClient = CreateWindowEx(WS_EX_CLIENTEDGE, "mdiclient", NULL, + WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL | WS_VISIBLE, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + hwnd, (HMENU)IDC_MAIN_MDI, GetModuleHandle(NULL), (LPVOID)&ccs); + + if(g_hMDIClient == NULL) + MessageBox(hwnd, "Could not create MDI client.", "Error", MB_OK | MB_ICONERROR); + + // Create Toolbar + + hTool = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, + hwnd, (HMENU)IDC_MAIN_TOOL, GetModuleHandle(NULL), NULL); + if(hTool == NULL) + MessageBox(hwnd, "Could not create tool bar.", "Error", MB_OK | MB_ICONERROR); + + // Send the TB_BUTTONSTRUCTSIZE message, which is required for + // backward compatibility. + SendMessage(hTool, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0); + + tbab.hInst = HINST_COMMCTRL; + tbab.nID = IDB_STD_SMALL_COLOR; + SendMessage(hTool, TB_ADDBITMAP, 0, (LPARAM)&tbab); + + ZeroMemory(tbb, sizeof(tbb)); + tbb[0].iBitmap = STD_FILENEW; + tbb[0].fsState = TBSTATE_ENABLED; + tbb[0].fsStyle = TBSTYLE_BUTTON; + tbb[0].idCommand = ID_FILE_NEW; + + tbb[1].iBitmap = STD_FILEOPEN; + tbb[1].fsState = TBSTATE_ENABLED; + tbb[1].fsStyle = TBSTYLE_BUTTON; + tbb[1].idCommand = ID_FILE_OPEN; + + tbb[2].iBitmap = STD_FILESAVE; + tbb[2].fsState = TBSTATE_ENABLED; + tbb[2].fsStyle = TBSTYLE_BUTTON; + tbb[2].idCommand = ID_FILE_SAVEAS; + + SendMessage(hTool, TB_ADDBUTTONS, sizeof(tbb)/sizeof(TBBUTTON), (LPARAM)&tbb); + + // Create Status bar + + hStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL, + WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0, + hwnd, (HMENU)IDC_MAIN_STATUS, GetModuleHandle(NULL), NULL); + + SendMessage(hStatus, SB_SETPARTS, sizeof(statwidths)/sizeof(int), (LPARAM)statwidths); + SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)"Hi there :)"); + } + break; + case WM_SIZE: + { + HWND hTool; + RECT rcTool; + int iToolHeight; + + HWND hStatus; + RECT rcStatus; + int iStatusHeight; + + HWND hMDI; + int iMDIHeight; + RECT rcClient; + + // Size toolbar and get height + + hTool = GetDlgItem(hwnd, IDC_MAIN_TOOL); + SendMessage(hTool, TB_AUTOSIZE, 0, 0); + + GetWindowRect(hTool, &rcTool); + iToolHeight = rcTool.bottom - rcTool.top; + + // Size status bar and get height + + hStatus = GetDlgItem(hwnd, IDC_MAIN_STATUS); + SendMessage(hStatus, WM_SIZE, 0, 0); + + GetWindowRect(hStatus, &rcStatus); + iStatusHeight = rcStatus.bottom - rcStatus.top; + + // Calculate remaining height and size edit + + GetClientRect(hwnd, &rcClient); + + iMDIHeight = rcClient.bottom - iToolHeight - iStatusHeight; + + hMDI = GetDlgItem(hwnd, IDC_MAIN_MDI); + SetWindowPos(hMDI, NULL, 0, iToolHeight, rcClient.right, iMDIHeight, SWP_NOZORDER); + } + break; + case WM_CLOSE: + DestroyWindow(hwnd); + break; + case WM_DESTROY: + PostQuitMessage(0); + break; + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case ID_FILE_EXIT: + PostMessage(hwnd, WM_CLOSE, 0, 0); + break; + case ID_FILE_NEW: + CreateNewMDIChild(g_hMDIClient); + break; + case ID_FILE_OPEN: + { + HWND hChild = CreateNewMDIChild(g_hMDIClient); + if(hChild) + { + DoFileOpen(hChild); + } + } + break; + case ID_FILE_CLOSE: + { + HWND hChild = (HWND)SendMessage(g_hMDIClient, WM_MDIGETACTIVE,0,0); + if(hChild) + { + SendMessage(hChild, WM_CLOSE, 0, 0); + } + } + break; + case ID_WINDOW_TILE: + SendMessage(g_hMDIClient, WM_MDITILE, 0, 0); + break; + case ID_WINDOW_CASCADE: + SendMessage(g_hMDIClient, WM_MDICASCADE, 0, 0); + break; + default: + { + if(LOWORD(wParam) >= ID_MDI_FIRSTCHILD) + { + DefFrameProc(hwnd, g_hMDIClient, WM_COMMAND, wParam, lParam); + } + else + { + HWND hChild = (HWND)SendMessage(g_hMDIClient, WM_MDIGETACTIVE,0,0); + if(hChild) + { + SendMessage(hChild, WM_COMMAND, wParam, lParam); + } + } + } + } + break; + default: + return DefFrameProc(hwnd, g_hMDIClient, msg, wParam, lParam); + } + return 0; +} + +LRESULT CALLBACK MDIChildWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch(msg) + { + case WM_CREATE: + { + HFONT hfDefault; + HWND hEdit; + + // Create Edit Control + + hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "", + WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL, + 0, 0, 100, 100, hwnd, (HMENU)IDC_CHILD_EDIT, GetModuleHandle(NULL), NULL); + if(hEdit == NULL) + MessageBox(hwnd, "Could not create edit box.", "Error", MB_OK | MB_ICONERROR); + + hfDefault = GetStockObject(DEFAULT_GUI_FONT); + SendMessage(hEdit, WM_SETFONT, (WPARAM)hfDefault, MAKELPARAM(FALSE, 0)); + } + break; + case WM_MDIACTIVATE: + { + HMENU hMenu, hFileMenu; + UINT EnableFlag; + + hMenu = GetMenu(g_hMainWindow); + if(hwnd == (HWND)lParam) + { //being activated, enable the menus + EnableFlag = MF_ENABLED; + } + else + { //being de-activated, gray the menus + EnableFlag = MF_GRAYED; + } + + EnableMenuItem(hMenu, 1, MF_BYPOSITION | EnableFlag); + EnableMenuItem(hMenu, 2, MF_BYPOSITION | EnableFlag); + + hFileMenu = GetSubMenu(hMenu, 0); + EnableMenuItem(hFileMenu, ID_FILE_SAVEAS, MF_BYCOMMAND | EnableFlag); + + EnableMenuItem(hFileMenu, ID_FILE_CLOSE, MF_BYCOMMAND | EnableFlag); + EnableMenuItem(hFileMenu, ID_FILE_CLOSEALL, MF_BYCOMMAND | EnableFlag); + + DrawMenuBar(g_hMainWindow); + } + break; + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case ID_FILE_OPEN: + DoFileOpen(hwnd); + break; + case ID_FILE_SAVEAS: + DoFileSave(hwnd); + break; + case ID_EDIT_CUT: + SendDlgItemMessage(hwnd, IDC_CHILD_EDIT, WM_CUT, 0, 0); + break; + case ID_EDIT_COPY: + SendDlgItemMessage(hwnd, IDC_CHILD_EDIT, WM_COPY, 0, 0); + break; + case ID_EDIT_PASTE: + SendDlgItemMessage(hwnd, IDC_CHILD_EDIT, WM_PASTE, 0, 0); + break; + } + break; + case WM_SIZE: + { + HWND hEdit; + RECT rcClient; + + // Calculate remaining height and size edit + + GetClientRect(hwnd, &rcClient); + + hEdit = GetDlgItem(hwnd, IDC_CHILD_EDIT); + SetWindowPos(hEdit, NULL, 0, 0, rcClient.right, rcClient.bottom, SWP_NOZORDER); + } + return DefMDIChildProc(hwnd, msg, wParam, lParam); + default: + return DefMDIChildProc(hwnd, msg, wParam, lParam); + + } + return 0; +} + +BOOL SetUpMDIChildWindowClass(HINSTANCE hInstance) +{ + WNDCLASSEX wc; + + wc.cbSize = sizeof(WNDCLASSEX); + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = MDIChildWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, (LPCTSTR)IDI_APPLICATION); + wc.hCursor = LoadCursor(NULL, (LPCTSTR)IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_3DFACE+1); + wc.lpszMenuName = NULL; + wc.lpszClassName = g_szChildClassName; + wc.hIconSm = LoadIcon(NULL, (LPCTSTR)IDI_APPLICATION); + + if(!RegisterClassEx(&wc)) + { + MessageBox(0, "Could Not Register Child Window", "Oh Oh...", + MB_ICONEXCLAMATION | MB_OK); + return FALSE; + } + else + return TRUE; +} + + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPSTR lpCmdLine, int nCmdShow) +{ + WNDCLASSEX wc; + HWND hwnd; + MSG Msg; + + InitCommonControls(); + + wc.cbSize = sizeof(WNDCLASSEX); + wc.style = 0; + wc.lpfnWndProc = WndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(NULL, (LPCTSTR)IDI_APPLICATION); + wc.hCursor = LoadCursor(NULL, (LPCTSTR)IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU); + wc.lpszClassName = g_szClassName; + wc.hIconSm = LoadIcon(NULL, (LPCTSTR)IDI_APPLICATION); + + if(!RegisterClassEx(&wc)) + { + MessageBox(NULL, "Window Registration Failed!", "Error!", + MB_ICONEXCLAMATION | MB_OK); + return 0; + } + + if(!SetUpMDIChildWindowClass(hInstance)) + return 0; + + hwnd = CreateWindowEx( + 0, + g_szClassName, + "MDI Test Application", + WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, + CW_USEDEFAULT, CW_USEDEFAULT, 480, 320, + NULL, NULL, hInstance, NULL); + + if(hwnd == NULL) + { + MessageBox(NULL, "Window Creation Failed!", "Error!", + MB_ICONEXCLAMATION | MB_OK); + return 0; + } + + g_hMainWindow = hwnd; + + ShowWindow(hwnd, nCmdShow); + UpdateWindow(hwnd); + + while(GetMessage(&Msg, NULL, 0, 0) > 0) + { + if (!TranslateMDISysAccel(g_hMDIClient, &Msg)) + { + TranslateMessage(&Msg); + DispatchMessage(&Msg); + } + } + return Msg.wParam; +} diff --git a/reactos/apps/tests/mdi/mdi.rc b/reactos/apps/tests/mdi/mdi.rc new file mode 100644 index 00000000000..c22ad1f55ae --- /dev/null +++ b/reactos/apps/tests/mdi/mdi.rc @@ -0,0 +1,30 @@ +#include +#include +#include "resource.h" + +IDR_MAINMENU MENU DISCARDABLE +BEGIN + POPUP "&File" + BEGIN + MENUITEM "&New", ID_FILE_NEW + MENUITEM "&Open...", ID_FILE_OPEN + MENUITEM "Save &As...", ID_FILE_SAVEAS, GRAYED + MENUITEM SEPARATOR + MENUITEM "&Close", ID_FILE_CLOSE, GRAYED + MENUITEM SEPARATOR + MENUITEM "E&xit", ID_FILE_EXIT + END + POPUP "&Edit", GRAYED + BEGIN + MENUITEM "C&ut", ID_EDIT_CUT + MENUITEM "&Copy", ID_EDIT_COPY + MENUITEM "&Paste", ID_EDIT_PASTE + END + POPUP "&Window", GRAYED + BEGIN + MENUITEM "&Tile", ID_WINDOW_TILE + MENUITEM "&Cascade", ID_WINDOW_CASCADE + END +END + + diff --git a/reactos/apps/tests/mdi/resource.h b/reactos/apps/tests/mdi/resource.h new file mode 100644 index 00000000000..3ea6b7e9560 --- /dev/null +++ b/reactos/apps/tests/mdi/resource.h @@ -0,0 +1,27 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by app_four.rc +// +#define IDR_MAINMENU 102 +#define ID_FILE_EXIT 40001 +#define ID_FILE_NEW 40002 +#define ID_FILE_OPEN 40003 +#define ID_FILE_SAVEAS 40005 +#define ID_WINDOW_CASCADE 40008 +#define ID_WINDOW_TILE 40009 +#define ID_FILE_CLOSE 40010 +#define ID_FILE_CLOSEALL 40011 +#define ID_EDIT_CUT 40015 +#define ID_EDIT_COPY 40016 +#define ID_EDIT_PASTE 40017 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40020 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif