reactos/rosapps/applications/imagesoft/mainwnd.c
Sylvain Petreolle 36cc36e73f [ROSAPPS]
Move imagesoft to applications and add it to build.
Convert lang files to UTF-8.
Fix casts and x64 warnings.
Patch by Hermes Belusca.
See bug 7185 for details.

svn path=/trunk/; revision=57201
2012-08-29 20:44:54 +00:00

1455 lines
42 KiB
C

#include <precomp.h>
static const TCHAR szMainWndClass[] = TEXT("ImageSoftWndClass");
#define ID_MDI_FIRSTCHILD 50000
#define ID_MDI_WINDOWMENU 5
#define NUM_FLT_WND 3
/* toolbar buttons */
TBBUTTON StdButtons[] = {
/* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */
{TBICON_NEW, ID_NEW, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}, /* new */
{TBICON_OPEN, ID_OPEN, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}, /* open */
{TBICON_SAVE, ID_SAVE, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}, /* save */
{10, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */
{TBICON_PRINT, ID_PRINTPRE, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* print */
{TBICON_PRINTPRE, ID_PRINT, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* print preview */
{10, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */
{TBICON_CUT, ID_CUT, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* cut */
{TBICON_COPY, ID_COPY, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* copy */
{TBICON_PASTE, ID_PASTE, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* paste */
{10, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */
{TBICON_UNDO, ID_UNDO, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* undo */
{TBICON_REDO, ID_REDO, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0 }, /* redo */
{10, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0},
};
TBBUTTON TextButtons[] = {
{10, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */
{TBICON_BOLD, ID_BOLD, TBSTATE_ENABLED, BTNS_BUTTON | TBSTYLE_CHECK, {0}, 0, 0}, /* bold */
{TBICON_ITALIC, ID_ITALIC, TBSTATE_ENABLED, BTNS_BUTTON | TBSTYLE_CHECK, {0}, 0, 0}, /* italic */
{TBICON_ULINE, ID_ULINE, TBSTATE_ENABLED, BTNS_BUTTON | TBSTYLE_CHECK, {0}, 0, 0}, /* underline */
{10, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */
{TBICON_TXTLEFT, ID_TXTLEFT, TBSTATE_ENABLED | TBSTATE_CHECKED, BTNS_BUTTON | TBSTYLE_GROUP | TBSTYLE_CHECK, {0}, 0, 0 }, /* left justified */
{TBICON_TXTCENTER,ID_TXTCENTER,TBSTATE_ENABLED, BTNS_BUTTON | TBSTYLE_GROUP | TBSTYLE_CHECK, {0}, 0, 0 }, /* centered */
{TBICON_TXTRIGHT, ID_TXTRIGHT, TBSTATE_ENABLED, BTNS_BUTTON | TBSTYLE_GROUP | TBSTYLE_CHECK, {0}, 0, 0 }, /* right justified */
{10, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */
};
/* menu hints */
static const MENU_HINT MainMenuHintTable[] = {
/* File Menu */
{ID_BLANK, IDS_HINT_BLANK},
{ID_NEW, IDS_HINT_NEW},
{ID_OPEN, IDS_HINT_OPEN},
{ID_CLOSE, IDS_HINT_CLOSE},
{ID_CLOSEALL, IDS_HINT_CLOSEALL},
{ID_SAVE, IDS_HINT_SAVE},
{ID_SAVEAS, IDS_HINT_SAVEAS},
{ID_PRINTPRE, IDS_HINT_PRINTPRE},
{ID_PRINT, IDS_HINT_PRINT},
{ID_PROP, IDS_HINT_PROP},
{ID_EXIT, IDS_HINT_EXIT},
/* view menu */
{ID_TOOLS, IDS_HINT_TOOLS},
{ID_COLOR, IDS_HINT_COLORS},
{ID_HISTORY, IDS_HINT_HISTORY},
{ID_STATUSBAR, IDS_HINT_STATUS},
/* Window Menu */
{ID_WINDOW_NEXT, IDS_HINT_NEXT},
{ID_WINDOW_CASCADE, IDS_HINT_CASCADE},
{ID_WINDOW_TILE_HORZ, IDS_HINT_TILE_HORZ},
{ID_WINDOW_TILE_VERT, IDS_HINT_TILE_VERT},
{ID_WINDOW_ARRANGE, IDS_HINT_ARRANGE}
};
static const MENU_HINT SystemMenuHintTable[] = {
{SC_RESTORE, IDS_HINT_SYS_RESTORE},
{SC_MOVE, IDS_HINT_SYS_MOVE},
{SC_SIZE, IDS_HINT_SYS_SIZE},
{SC_MINIMIZE, IDS_HINT_SYS_MINIMIZE},
{SC_MAXIMIZE, IDS_HINT_SYS_MAXIMIZE},
{SC_CLOSE, IDS_HINT_CLOSE},
{SC_NEXTWINDOW, IDS_HINT_NEXT},
};
/* Toolbars */
#define ID_TOOLBAR_STANDARD 0
#define ID_TOOLBAR_TEXT 1
static const TCHAR szToolbarStandard[] = TEXT("STANDARD");
static const TCHAR szToolbarText[] = TEXT("TEXT");
/* Test Toolbar */
#define ID_TOOLBAR_TEST 5
static const TCHAR szToolbarTest[] = TEXT("TEST");
/* Toolbars table */
static const DOCKBAR MainDockBars[] = {
{ID_TOOLBAR_STANDARD, szToolbarStandard, IDS_TOOLBAR_STANDARD, TOP_DOCK},
{ID_TOOLBAR_TEST, szToolbarTest, IDS_TOOLBAR_TEST, TOP_DOCK},
{ID_TOOLBAR_TEXT, szToolbarText, IDS_TOOLBAR_TEXT, TOP_DOCK},
};
static BOOL CALLBACK
MainWndCreateToolbarClient(struct _TOOLBAR_DOCKS *TbDocks,
const DOCKBAR *Dockbar,
PVOID Context,
HWND hParent,
HWND *hwnd)
{
const TBBUTTON *Buttons = NULL;
UINT NumButtons = 0;
UINT StartImageRes = 0;
HWND hWndClient = NULL;
UNREFERENCED_PARAMETER(Context);
switch (Dockbar->BarId)
{
case ID_TOOLBAR_STANDARD:
{
Buttons = StdButtons;
NumButtons = sizeof(StdButtons) / sizeof(StdButtons[0]);
StartImageRes = IDB_MAINNEWICON;
break;
}
case ID_TOOLBAR_TEXT:
{
Buttons = TextButtons;
NumButtons = sizeof(TextButtons) / sizeof(TextButtons[0]);
StartImageRes = IDB_TEXTBOLD;
break;
}
case ID_TOOLBAR_TEST:
{/*
hWndClient = CreateWindowEx(WS_EX_TOOLWINDOW,
TEXT("BUTTON"),
TEXT("Test Button"),
WS_CHILD | WS_VISIBLE,
0,
0,
150,
25,
hParent,
NULL,
hInstance,
NULL);*/
break;
}
}
if (Buttons != NULL)
{
hWndClient = CreateWindowEx(0,
TOOLBARCLASSNAME,
NULL,
WS_CHILD | WS_CLIPSIBLINGS |
CCS_NOPARENTALIGN | CCS_NOMOVEY | CCS_NORESIZE | CCS_NODIVIDER |
TBSTYLE_FLAT | TBSTYLE_TOOLTIPS,
0,
0,
0,
0,
hParent,
NULL,
hInstance,
NULL);
if (hWndClient != NULL)
{
HIMAGELIST hImageList;
SendMessage(hWndClient,
TB_SETEXTENDEDSTYLE,
0,
TBSTYLE_EX_HIDECLIPPEDBUTTONS);
SendMessage(hWndClient,
TB_BUTTONSTRUCTSIZE,
sizeof(Buttons[0]),
0);
SendMessage(hWndClient,
TB_SETBITMAPSIZE,
0,
(LPARAM)MAKELONG(TB_BMP_WIDTH, TB_BMP_HEIGHT));
hImageList = InitImageList(NumButtons,
StartImageRes);
ImageList_Destroy((HIMAGELIST)SendMessage(hWndClient,
TB_SETIMAGELIST,
0,
(LPARAM)hImageList));
SendMessage(hWndClient,
TB_ADDBUTTONS,
NumButtons,
(LPARAM)Buttons);
}
}
switch (Dockbar->BarId)
{
case ID_TOOLBAR_TEXT:
{
HWND hFontType;
HWND hFontSize;
/* font selection combo */
hFontType = CreateWindowEx(0,
WC_COMBOBOX,
NULL,
WS_CHILD | WS_VISIBLE | WS_VSCROLL |
CBS_DROPDOWN | CBS_SORT | CBS_HASSTRINGS, //| CBS_OWNERDRAWFIXED,
0, 0, 120, 0,
hParent,
NULL,
hInstance,
NULL);
if (hFontType != NULL)
{
MakeFlatCombo(hFontType);
SetParent(hFontType,
hWndClient);
if (!ToolbarInsertSpaceForControl(hWndClient,
hFontType,
0,
ID_TXTFONTNAME,
TRUE))
{
DestroyWindow(hFontType);
}
/* Create the list of fonts */
FillFontStyleComboList(hFontType);
}
/* font size combo */
hFontSize = CreateWindowEx(0,
WC_COMBOBOX,
NULL,
WS_CHILD | WS_VISIBLE | CBS_DROPDOWN,
0, 0, 50, 0,
hParent,
NULL,
hInstance,
NULL);
if (hFontSize != NULL)
{
MakeFlatCombo(hFontSize);
SetParent(hFontSize,
hWndClient);
if (!ToolbarInsertSpaceForControl(hWndClient,
hFontSize,
1,
ID_TXTFONTSIZE,
TRUE))
{
DestroyWindow(hFontSize);
}
/* Update the font-size-list */
FillFontSizeComboList(hFontSize);
}
break;
}
}
if (hWndClient != NULL)
{
*hwnd = hWndClient;
return TRUE;
}
return FALSE;
}
static BOOL CALLBACK
MainWndDestroyToolbarClient(struct _TOOLBAR_DOCKS *TbDocks,
const DOCKBAR *Dockbar,
PVOID Context,
HWND hwnd)
{
UNREFERENCED_PARAMETER(TbDocks);
UNREFERENCED_PARAMETER(Dockbar);
UNREFERENCED_PARAMETER(Context);
DestroyWindow(hwnd);
return TRUE;
}
static BOOL CALLBACK
MainWndToolbarInsertBand(struct _TOOLBAR_DOCKS *TbDocks,
const DOCKBAR *Dockbar,
PVOID Context,
UINT *Index,
LPREBARBANDINFO rbi)
{
switch (rbi->wID)
{
case ID_TOOLBAR_TEXT:
case ID_TOOLBAR_STANDARD:
{
SIZE Size;
if (SendMessage(rbi->hwndChild,
TB_GETMAXSIZE,
0,
(LPARAM)&Size))
{
rbi->fStyle |= RBBS_USECHEVRON | RBBS_HIDETITLE;
rbi->fMask |= RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE;
rbi->cx = rbi->cxIdeal = Size.cx;
rbi->cxMinChild = 0;
rbi->cyMinChild = Size.cy;
}
break;
}
case ID_TOOLBAR_TEST:
{
RECT rcBtn;
if (GetWindowRect(rbi->hwndChild,
&rcBtn))
{
rbi->fStyle |= RBBS_HIDETITLE;
rbi->fMask |= RBBIM_SIZE | RBBIM_CHILDSIZE;
rbi->cx = rcBtn.right - rcBtn.left;
rbi->cxMinChild = 0;
rbi->cyMinChild = rcBtn.bottom - rcBtn.top;
}
break;
}
}
return TRUE;
}
static VOID
TbCustomControlChange(HWND hWndToolbar,
HWND hWndControl,
BOOL Vert)
{
/* the toolbar changed from horizontal to vertical or vice versa... */
return;
}
static VOID CALLBACK
MainWndToolbarDockBand(struct _TOOLBAR_DOCKS *TbDocks,
const DOCKBAR *Dockbar,
PVOID Context,
DOCK_POSITION DockFrom,
DOCK_POSITION DockTo,
LPREBARBANDINFO rbi)
{
if (rbi->fMask & RBBIM_CHILD && rbi->hwndChild != NULL)
{
switch (rbi->wID)
{
case ID_TOOLBAR_TEXT:
case ID_TOOLBAR_STANDARD:
{
SIZE Size;
BOOL Vert;
DWORD dwStyle = (DWORD)SendMessage(rbi->hwndChild,
TB_GETSTYLE,
0,
0);
switch (DockTo)
{
case LEFT_DOCK:
case RIGHT_DOCK:
dwStyle |= CCS_VERT | TBSTYLE_WRAPABLE;
Vert = TRUE;
break;
default:
dwStyle &= ~(CCS_VERT | TBSTYLE_WRAPABLE);
Vert = FALSE;
break;
}
SendMessage(rbi->hwndChild,
TB_SETSTYLE,
0,
(LPARAM)dwStyle);
ToolbarUpdateControlSpaces(rbi->hwndChild,
TbCustomControlChange);
if (SendMessage(rbi->hwndChild,
TB_GETMAXSIZE,
0,
(LPARAM)&Size))
{
rbi->fMask |= RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE;
rbi->cx = rbi->cxIdeal = (Vert ? Size.cy : Size.cx);
rbi->cxMinChild = 0;
rbi->cyMinChild = (Vert ? Size.cx : Size.cy);
}
break;
}
case ID_TOOLBAR_TEST:
{
if (DockTo == NO_DOCK)
{
rbi->fMask |= RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_IDEALSIZE;
rbi->cx = rbi->cxIdeal = 150;
rbi->cxMinChild = 0;
rbi->cyMinChild = 40;
}
break;
}
}
}
}
static VOID CALLBACK
MainWndToolbarChevronPushed(struct _TOOLBAR_DOCKS *TbDocks,
const DOCKBAR *Dockbar,
PVOID Context,
HWND hwndChild,
LPNMREBARCHEVRON lpnm)
{
switch (lpnm->wID)
{
case ID_TOOLBAR_STANDARD:
{
MapWindowPoints(lpnm->hdr.hwndFrom,
HWND_DESKTOP,
(LPPOINT)&lpnm->rc,
2);
/* Create a popup menu for all toolbar icons hidden */
break;
}
}
}
static VOID
MainWndMoveFloatingWindows(PMAIN_WND_INFO Info,
PRECT wndOldPos)
{
RECT wndNewPos, TbRect;
INT i, xMoved, yMoved;
PFLT_WND WndArr[NUM_FLT_WND];
if (GetWindowRect(Info->hSelf,
&wndNewPos))
{
xMoved = wndNewPos.left - wndOldPos->left;
yMoved = wndNewPos.top - wndOldPos->top;
/* store the pointers in an array */
WndArr[0] = Info->fltTools;
WndArr[1] = Info->fltColors;
WndArr[2] = Info->fltHistory;
for (i = 0; i < NUM_FLT_WND; i++)
{
GetWindowRect(WndArr[i]->hSelf,
&TbRect);
WndArr[i]->x = TbRect.left + xMoved;
WndArr[i]->y = TbRect.top + yMoved;
MoveWindow(WndArr[i]->hSelf,
WndArr[i]->x,
WndArr[i]->y,
WndArr[i]->Width,
WndArr[i]->Height,
TRUE);
}
CopyMemory(wndOldPos,
&wndNewPos,
sizeof(RECT));
}
}
static VOID
MainWndResetFloatingWindows(PMAIN_WND_INFO Info)
{
RECT rect;
if (GetWindowRect(Info->hMdiClient,
&rect))
{
/* tools datum */
MoveWindow(Info->fltTools->hSelf,
rect.left + 5,
rect.top + 5,
Info->fltTools->Width,
Info->fltTools->Height,
TRUE);
/* colors datum */
MoveWindow(Info->fltColors->hSelf,
rect.left + 5,
rect.bottom - Info->fltColors->Height - 5,
Info->fltColors->Width,
Info->fltColors->Height,
TRUE);
/* history datum */
MoveWindow(Info->fltHistory->hSelf,
rect.right - Info->fltHistory->Width - 5,
rect.top + 5,
Info->fltHistory->Width,
Info->fltHistory->Height,
TRUE);
}
}
static VOID
MainWndCreateFloatWindows(PMAIN_WND_INFO Info)
{
RECT rect;
HMENU hMenu;
UINT Res;
PFLT_WND WndArr[NUM_FLT_WND]; /* temp array for looping */
INT i;
Info->fltTools = HeapAlloc(ProcessHeap,
HEAP_ZERO_MEMORY,
sizeof(FLT_WND));
Info->fltColors = HeapAlloc(ProcessHeap,
HEAP_ZERO_MEMORY,
sizeof(FLT_WND));
Info->fltHistory = HeapAlloc(ProcessHeap,
HEAP_ZERO_MEMORY,
sizeof(FLT_WND));
/* set window dimensions */
Info->fltTools->Width = 53;
Info->fltTools->Height = 300;
Info->fltColors->Width = 200;
Info->fltColors->Height = 200;
Info->fltHistory->Width = 150;
Info->fltHistory->Height = 150;
if (! GetWindowRect(Info->hMdiClient,
&rect))
{
return;
}
/* Set window datums */
Info->fltTools->x = rect.left + 5;
Info->fltTools->y = rect.top + 5;
Info->fltColors->x = rect.left + 5;
Info->fltColors->y = rect.bottom - Info->fltColors->Height - 5;
Info->fltHistory->x = rect.right - Info->fltHistory->Width - 5;
Info->fltHistory->y = rect.top + 5;
/* save pointers into array incrementing within the loop*/
WndArr[0] = Info->fltTools;
WndArr[1] = Info->fltColors;
WndArr[2] = Info->fltHistory;
for (i = 0, Res = IDS_FLT_TOOLS; Res < IDS_FLT_TOOLS + NUM_FLT_WND; Res++, i++)
{
if (! AllocAndLoadString(&WndArr[i]->lpName,
hInstance,
Res))
{
WndArr[i]->lpName = NULL;
}
WndArr[i]->hSelf = CreateWindowEx(WS_EX_TOOLWINDOW,
TEXT("ImageSoftFloatWndClass"),
WndArr[i]->lpName,
WS_POPUPWINDOW | WS_DLGFRAME | WS_VISIBLE,
WndArr[i]->x,
WndArr[i]->y,
WndArr[i]->Width,
WndArr[i]->Height,
Info->hSelf,
NULL,
hInstance,
WndArr[i]);
ShowWindow(WndArr[i]->hSelf, SW_HIDE);
}
hMenu = GetMenu(Info->hSelf);
if (Info->fltTools->hSelf != NULL)
{
if (FloatToolbarCreateToolsGui(Info))
{
CheckMenuItem(hMenu,
ID_TOOLS,
MF_CHECKED);
ShowHideWindow(Info->fltTools->hSelf);
}
}
if (Info->fltColors->hSelf != NULL)
{
if (FloatToolbarCreateColorsGui(Info))
{
}
}
if (Info->fltHistory->hSelf != NULL)
{
if (FloatToolbarCreateHistoryGui(Info))
{
}
}
}
static VOID
MainWndDestroyFloatWindows(PMAIN_WND_INFO Info)
{
if (Info->fltTools != NULL)
HeapFree(ProcessHeap, 0, Info->fltTools);
if (Info->fltColors != NULL)
HeapFree(ProcessHeap, 0, Info->fltColors);
if (Info->fltHistory != NULL)
HeapFree(ProcessHeap, 0, Info->fltHistory);
}
static const DOCKBAR_ITEM_CALLBACKS MainWndDockBarCallbacks = {
MainWndCreateToolbarClient,
MainWndDestroyToolbarClient,
MainWndToolbarInsertBand,
MainWndToolbarDockBand,
MainWndToolbarChevronPushed,
};
static VOID
CreateToolbars(PMAIN_WND_INFO Info)
{
UINT i;
for (i = 0; i < sizeof(MainDockBars) / sizeof(MainDockBars[0]); i++)
{
/* FIXME - lookup whether to display the toolbar */
TbdAddToolbar(&Info->ToolDocks,
&MainDockBars[i],
Info,
&MainWndDockBarCallbacks);
}
MainWndCreateFloatWindows(Info);
}
static VOID CALLBACK
MainWndResize(PVOID Context,
LONG cx,
LONG cy)
{
RECT rcClient = {0};
RECT rcStatus = {0};
HDWP dwp;
INT DocksVisible;
PMAIN_WND_INFO Info = (PMAIN_WND_INFO)Context;
/* Calculate the MDI client rectangle */
rcClient.right = cx;
rcClient.bottom = cy;
if (Info->hStatus != NULL)
{
GetWindowRect(Info->hStatus,
&rcStatus);
rcClient.bottom -= (rcStatus.bottom - rcStatus.top);
}
/* Adjust the client rect if docked toolbars are visible */
DocksVisible = TbdAdjustUpdateClientRect(&Info->ToolDocks,
&rcClient);
dwp = BeginDeferWindowPos(2 + DocksVisible);
if (dwp != NULL)
{
/* Update the toolbar docks */
if (DocksVisible != 0)
{
dwp = TbdDeferDocks(dwp,
&Info->ToolDocks);
if (dwp == NULL)
return;
}
/* Update the MDI client */
if (Info->hMdiClient != NULL)
{
dwp = DeferWindowPos(dwp,
Info->hMdiClient,
NULL,
rcClient.left,
rcClient.top,
rcClient.right - rcClient.left,
rcClient.bottom - rcClient.top,
SWP_NOZORDER);
if (dwp == NULL)
return;
}
/* Update the status bar */
if (Info->hStatus != NULL)
{
dwp = DeferWindowPos(dwp,
Info->hStatus,
NULL,
0,
cy - (rcStatus.bottom - rcStatus.top),
cx,
rcStatus.bottom - rcStatus.top,
SWP_NOZORDER);
if (dwp == NULL)
return;
}
EndDeferWindowPos(dwp);
}
}
static VOID
InitMainWnd(PMAIN_WND_INFO Info)
{
CLIENTCREATESTRUCT ccs;
INT statwidths[] = {110, -1};
/* FIXME - create controls and initialize the application */
/* create the status bar */
Info->hStatus = CreateWindowEx(0,
STATUSCLASSNAME,
NULL,
WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | CCS_NOPARENTALIGN | SBARS_SIZEGRIP,
0,
0,
0,
0,
Info->hSelf,
(HMENU)IDC_STATUSBAR,
hInstance,
NULL);
if (Info->hStatus != NULL)
SendMessage(Info->hStatus,
SB_SETPARTS,
sizeof(statwidths)/sizeof(int),
(LPARAM)statwidths);
/* create the MDI client window */
ccs.hWindowMenu = GetSubMenu(GetMenu(Info->hSelf),
ID_MDI_WINDOWMENU);
ccs.idFirstChild = ID_MDI_FIRSTCHILD;
Info->hMdiClient = CreateWindowEx(WS_EX_ACCEPTFILES | WS_EX_CLIENTEDGE,
TEXT("MDICLIENT"),
NULL,
WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VSCROLL | WS_HSCROLL,
0,
0,
0,
0,
Info->hSelf,
NULL,
hInstance,
&ccs);
TbdInitializeDocks(&Info->ToolDocks,
Info->hSelf,
Info,
MainWndResize);
CreateToolbars(Info);
/* initialize file open/save structure */
FileInitialize(Info->hSelf);
}
static VOID
MainWndCommand(PMAIN_WND_INFO Info,
WORD CmdId,
HWND hControl)
{
static TCHAR szFileName[MAX_PATH];
static TCHAR szImageName[MAX_PATH];
UNREFERENCED_PARAMETER(hControl);
switch (CmdId)
{
case ID_NEW:
{
MessageBox(NULL, _T("Not yet implemented"), NULL, 0);
}
break;
case ID_OPEN:
{
OPEN_IMAGE_EDIT_INFO OpenInfo;
if (DoOpenFile(Info->hSelf,
szFileName, /* full file path */
szImageName)) /* file name */
{
OpenInfo.CreateNew = FALSE;
OpenInfo.Open.lpImagePath = szFileName;
OpenInfo.lpImageName = szImageName;
CreateImageEditWindow(Info,
&OpenInfo);
/* FIXME: move flt wnd's if scroll bars show
MainWndResetFloatingWindows(Info->hMdiClient); */
}
}
break;
case ID_TOOLS:
{
HMENU hMenu = GetMenu(Info->hSelf);
if (hMenu != NULL)
{
UINT uCheck = MF_CHECKED;
if (ShowHideWindow(Info->fltTools->hSelf))
uCheck = MF_UNCHECKED;
CheckMenuItem(hMenu,
ID_TOOLS,
uCheck);
}
}
break;
case ID_COLOR:
{
HMENU hMenu = GetMenu(Info->hSelf);
if (hMenu != NULL)
{
UINT uCheck = MF_CHECKED;
if (ShowHideWindow(Info->fltColors->hSelf))
uCheck = MF_UNCHECKED;
CheckMenuItem(hMenu,
ID_COLOR,
uCheck);
}
}
break;
case ID_HISTORY:
{
HMENU hMenu = GetMenu(Info->hSelf);
if (hMenu != NULL)
{
UINT uCheck = MF_CHECKED;
if (ShowHideWindow(Info->fltHistory->hSelf))
uCheck = MF_UNCHECKED;
CheckMenuItem(hMenu,
ID_HISTORY,
uCheck);
}
}
break;
case ID_BRIGHTNESS:
DialogBoxParam(hInstance,
MAKEINTRESOURCE(IDD_BRIGHTNESS),
Info->hSelf,
BrightnessProc,
(LPARAM)Info);
break;
case ID_CONTRAST:
/* FIXME : Create a window for contrast */
break;
case ID_BLACKANDWHITE:
{
if (Info->ImageEditors)
{
DisplayBlackAndWhite(Info->ImageEditors->hSelf,
Info->ImageEditors->hDCMem,
Info->ImageEditors->hBitmap);
}
}
break;
case ID_INVERTCOLORS:
{
if (Info->ImageEditors)
{
DisplayInvertedColors(Info->ImageEditors->hSelf,
Info->ImageEditors->hDCMem,
Info->ImageEditors->hBitmap);
}
}
break;
case ID_BLUR:
{
if (Info->ImageEditors)
{
DisplayBlur(Info->ImageEditors->hSelf,
Info->ImageEditors->hDCMem,
Info->ImageEditors->hBitmap);
}
}
break;
case ID_SHARPEN:
{
if (Info->ImageEditors)
{
DisplaySharpness(Info->ImageEditors->hSelf,
Info->ImageEditors->hDCMem,
Info->ImageEditors->hBitmap);
}
}
break;
case ID_EXIT:
SendMessage(Info->hSelf,
WM_CLOSE,
0,
0);
break;
/* Window Menu */
case ID_WINDOW_TILE_HORZ:
SendMessage(Info->hMdiClient,
WM_MDITILE,
MDITILE_HORIZONTAL,
0);
break;
case ID_WINDOW_TILE_VERT:
SendMessage(Info->hMdiClient,
WM_MDITILE,
MDITILE_VERTICAL,
0);
break;
case ID_WINDOW_CASCADE:
SendMessage(Info->hMdiClient,
WM_MDICASCADE,
0,
0);
break;
case ID_WINDOW_ARRANGE:
SendMessage(Info->hMdiClient,
WM_MDIICONARRANGE,
0,
0);
break;
case ID_WINDOW_NEXT:
SendMessage(Info->hMdiClient,
WM_MDINEXT,
0,
0);
break;
/* Help Menu */
case ID_ABOUT:
DialogBox(hInstance,
MAKEINTRESOURCE(IDD_ABOUTBOX),
Info->hSelf,
AboutDialogProc);
break;
}
}
static VOID
DestroyMainWnd(PMAIN_WND_INFO Info)
{
/* FIXME - cleanup allocated resources */
MainWndDestroyFloatWindows(Info);
}
static VOID
UpdateMainStatusBar(PMAIN_WND_INFO Info)
{
if (Info->hStatus != NULL)
{
SendMessage(Info->hStatus,
SB_SIMPLE,
(WPARAM)Info->InMenuLoop,
0);
}
}
static BOOL
MainWndMenuHint(PMAIN_WND_INFO Info,
WORD CmdId,
const MENU_HINT *HintArray,
DWORD HintsCount,
UINT DefHintId)
{
BOOL Found = FALSE;
const MENU_HINT *LastHint;
UINT HintId = DefHintId;
LastHint = HintArray + HintsCount;
while (HintArray != LastHint)
{
if (HintArray->CmdId == CmdId)
{
HintId = HintArray->HintId;
Found = TRUE;
break;
}
HintArray++;
}
StatusBarLoadString(Info->hStatus,
SB_SIMPLEID,
hInstance,
HintId);
return Found;
}
static LRESULT CALLBACK
MainWndProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
PMAIN_WND_INFO Info;
LRESULT Ret = 0;
static BOOL bLBMouseDown = FALSE;
static RECT wndOldPos;
/* Get the window context */
Info = (PMAIN_WND_INFO)GetWindowLongPtr(hwnd,
GWLP_USERDATA);
if (Info == NULL && uMsg != WM_CREATE)
{
goto HandleDefaultMessage;
}
switch (uMsg)
{
case WM_SIZE:
{
MainWndResize(Info,
LOWORD(lParam),
HIWORD(lParam));
/* NOTE - do *not* forward this message to DefFrameProc! Otherwise the MDI client
will attempt to resize itself */
/* reposition the floating toolbars */
if ((wParam == SIZE_MAXIMIZED) || (wParam == SIZE_RESTORED))
MainWndResetFloatingWindows(Info);
break;
}
case WM_NCLBUTTONDOWN:
bLBMouseDown = TRUE;
DefWindowProc(hwnd,
uMsg,
wParam,
lParam);
break;
case WM_NCLBUTTONUP:
bLBMouseDown = FALSE;
DefWindowProc(hwnd,
uMsg,
wParam,
lParam);
break;
case WM_MOVE:
{
/* if the main window is moved, move the toolbars too */
if (bLBMouseDown)
MainWndMoveFloatingWindows(Info, &wndOldPos);
}
break;
case WM_NOTIFY:
{
UINT BarId;
LPNMHDR pnmhdr = (LPNMHDR)lParam;
if (!TbdHandleNotifications(&Info->ToolDocks,
pnmhdr,
&Ret))
{
if (TbdDockBarIdFromClientWindow(&Info->ToolDocks,
pnmhdr->hwndFrom,
&BarId))
{
switch (BarId)
{
case ID_TOOLBAR_TEXT:
switch (pnmhdr->code)
{
case TBN_DELETINGBUTTON:
{
LPNMTOOLBAR lpnmtb = (LPNMTOOLBAR)lParam;
ToolbarDeleteControlSpace(pnmhdr->hwndFrom,
&lpnmtb->tbButton);
break;
}
}
break;
}
}
}
break;
}
case WM_COMMAND:
{
MainWndCommand(Info,
LOWORD(wParam),
(HWND)lParam);
goto HandleDefaultMessage;
}
case WM_MENUSELECT:
{
if (Info->hStatus != NULL)
{
if (!MainWndMenuHint(Info,
LOWORD(wParam),
MainMenuHintTable,
sizeof(MainMenuHintTable) / sizeof(MainMenuHintTable[0]),
IDS_HINT_BLANK))
{
MainWndMenuHint(Info,
LOWORD(wParam),
SystemMenuHintTable,
sizeof(SystemMenuHintTable) / sizeof(SystemMenuHintTable[0]),
IDS_HINT_BLANK);
}
}
break;
}
case WM_ENTERMENULOOP:
{
Info->InMenuLoop = TRUE;
UpdateMainStatusBar(Info);
break;
}
case WM_EXITMENULOOP:
{
Info->InMenuLoop = FALSE;
UpdateMainStatusBar(Info);
break;
}
case WM_CLOSE:
{
DestroyWindow(hwnd);
break;
}
case WM_ENABLE:
{
TbdHandleEnabling(&Info->ToolDocks,
hwnd,
(BOOL)wParam);
goto HandleDefaultMessage;
}
case WM_NCACTIVATE:
{
TbdHandleActivation(&Info->ToolDocks,
hwnd,
&wParam,
&lParam);
goto HandleDefaultMessage;
}
case WM_ACTIVATEAPP:
{
//TbdShowFloatingToolbars(&Info->ToolDocks,
// (BOOL)wParam);
goto HandleDefaultMessage;
}
case WM_CREATE:
{
Info = (PMAIN_WND_INFO)(((LPCREATESTRUCT)lParam)->lpCreateParams);
/* Initialize the main window context */
Info->hSelf = hwnd;
SetWindowLongPtr(hwnd,
GWLP_USERDATA,
(LONG_PTR)Info);
InitMainWnd(Info);
/* Show the window */
ShowWindow(hwnd,
Info->nCmdShow);
/* get the windows position */
GetWindowRect(hwnd,
&wndOldPos);
break;
}
case WM_DESTROY:
{
DestroyMainWnd(Info);
HeapFree(ProcessHeap,
0,
Info);
SetWindowLongPtr(hwnd,
GWLP_USERDATA,
0);
/* Break the message queue loop */
PostQuitMessage(0);
break;
}
default:
{
HandleDefaultMessage:
if (Info != NULL && Info->hMdiClient != NULL)
{
Ret = DefFrameProc(hwnd,
Info->hMdiClient,
uMsg,
wParam,
lParam);
}
else
{
Ret = DefWindowProc(hwnd,
uMsg,
wParam,
lParam);
}
break;
}
}
return Ret;
}
MDI_EDITOR_TYPE
MainWndGetCurrentEditor(PMAIN_WND_INFO MainWnd,
PVOID *Info)
{
MDI_EDITOR_TYPE EditorType;
if (MainWnd->ActiveEditor != NULL)
{
EditorType = *((PMDI_EDITOR_TYPE)MainWnd->ActiveEditor);
*Info = MainWnd->ActiveEditor;
}
else
{
EditorType = metUnknown;
*Info = NULL;
}
return EditorType;
}
VOID
MainWndSwitchEditorContext(PMAIN_WND_INFO Info,
HWND hDeactivate,
HWND hActivate)
{
PMDI_EDITOR_TYPE EditorType;
/* FIXME - optimize light weight switching
when switching from and to an editor of same type */
if (hDeactivate != NULL)
{
EditorType = (PMDI_EDITOR_TYPE)GetWindowLongPtr(hDeactivate,
GWLP_USERDATA);
if (EditorType != NULL)
{
switch (*EditorType)
{
case metImageEditor:
SetImageEditorEnvironment((PEDIT_WND_INFO)EditorType,
FALSE);
break;
default:
break;
}
Info->ActiveEditor = NULL;
}
}
if (hActivate != NULL)
{
EditorType = (PMDI_EDITOR_TYPE)GetWindowLongPtr(hActivate,
GWLP_USERDATA);
if (EditorType != NULL)
{
Info->ActiveEditor = EditorType;
switch (*EditorType)
{
case metImageEditor:
SetImageEditorEnvironment((PEDIT_WND_INFO)EditorType,
TRUE);
break;
default:
break;
}
}
}
}
HWND
CreateMainWindow(LPCTSTR lpCaption,
int nCmdShow)
{
PMAIN_WND_INFO Info;
HWND hMainWnd = NULL;
Info = HeapAlloc(ProcessHeap,
0,
sizeof(MAIN_WND_INFO));
if (Info != NULL)
{
ZeroMemory(Info,
sizeof(MAIN_WND_INFO));
Info->nCmdShow = nCmdShow;
/* FIXME - load the window position from the registry */
hMainWnd = CreateWindowEx(WS_EX_WINDOWEDGE,
szMainWndClass,
lpCaption,
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
Info);
if (hMainWnd == NULL)
{
HeapFree(ProcessHeap,
0,
Info);
}
}
return hMainWnd;
}
BOOL
MainWndTranslateMDISysAccel(HWND hwnd,
LPMSG lpMsg)
{
PMAIN_WND_INFO Info;
/* Get the window context */
Info = (PMAIN_WND_INFO)GetWindowLongPtr(hwnd,
GWLP_USERDATA);
if (Info != NULL && Info->hMdiClient != NULL)
{
return TranslateMDISysAccel(Info->hMdiClient,
lpMsg);
}
return FALSE;
}
BOOL
InitMainWindowImpl(VOID)
{
WNDCLASSEX wc = {0};
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = MainWndProc;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance,
MAKEINTRESOURCE(IDI_IMAGESOFTICON));
wc.hCursor = LoadCursor(NULL,
IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU);
wc.lpszClassName = szMainWndClass;
wc.hIconSm = (HICON)LoadImage(hInstance,
MAKEINTRESOURCE(IDI_IMAGESOFTICON),
IMAGE_ICON,
16,
16,
LR_SHARED);
return RegisterClassEx(&wc) != (ATOM)0;
}
VOID
UninitMainWindowImpl(VOID)
{
UnregisterClass(szMainWndClass,
hInstance);
}