mirror of
https://github.com/reactos/reactos.git
synced 2024-12-26 17:14:41 +00:00
456be5d16b
svn path=/trunk/; revision=15091
523 lines
12 KiB
C
523 lines
12 KiB
C
/*
|
|
Thanks to theForger from winprog.org
|
|
*/
|
|
#include <windows.h>
|
|
#include <commctrl.h>
|
|
|
|
#include <string.h>
|
|
#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;
|
|
}
|