From 16e3082c3dcefca8e535ec055679c1fdb77de6ca Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Sun, 26 Feb 2006 16:26:03 +0000 Subject: [PATCH] - Complete overhaul of imagesoft from Thomas Weidenmueller - Includes the addition of docking toolbars using the Win32 API svn path=/trunk/; revision=21201 --- reactos/base/applications/imagesoft/En.rc | 107 +- reactos/base/applications/imagesoft/about.c | 6 +- .../base/applications/imagesoft/imagesoft.c | 819 +------------ .../base/applications/imagesoft/imagesoft.h | 24 - .../applications/imagesoft/imagesoft.rbuild | 53 +- .../base/applications/imagesoft/imagesoft.rc | 2 + .../base/applications/imagesoft/imgedwnd.c | 296 +++++ reactos/base/applications/imagesoft/mainwnd.c | 905 +++++++++++++++ .../base/applications/imagesoft/manifest.xml | 24 + reactos/base/applications/imagesoft/misc.c | 160 +++ .../base/applications/imagesoft/opensave.c | 2 +- reactos/base/applications/imagesoft/precomp.h | 255 ++++ .../base/applications/imagesoft/resource.h | 28 +- .../base/applications/imagesoft/tooldock.c | 1032 +++++++++++++++++ 14 files changed, 2846 insertions(+), 867 deletions(-) delete mode 100644 reactos/base/applications/imagesoft/imagesoft.h create mode 100644 reactos/base/applications/imagesoft/imgedwnd.c create mode 100644 reactos/base/applications/imagesoft/mainwnd.c create mode 100644 reactos/base/applications/imagesoft/manifest.xml create mode 100644 reactos/base/applications/imagesoft/misc.c create mode 100644 reactos/base/applications/imagesoft/precomp.h create mode 100644 reactos/base/applications/imagesoft/tooldock.c diff --git a/reactos/base/applications/imagesoft/En.rc b/reactos/base/applications/imagesoft/En.rc index b12344b1ec3..4e8f9197a1d 100644 --- a/reactos/base/applications/imagesoft/En.rc +++ b/reactos/base/applications/imagesoft/En.rc @@ -2,62 +2,67 @@ IDR_MAINMENU MENU BEGIN POPUP "&File" BEGIN - MENUITEM "New...", ID_NEW - MENUITEM "Open...", ID_OPEN - MENUITEM "Close", ID_CLOSE, GRAYED - MENUITEM "Close all", ID_CLOSEALL, GRAYED + MENUITEM "&New...", ID_NEW + MENUITEM "&Open...", ID_OPEN MENUITEM SEPARATOR - MENUITEM "Save", ID_SAVE, GRAYED - MENUITEM "Save As", ID_SAVEAS, GRAYED + MENUITEM "&Close\tCtrl+F4", ID_CLOSE, GRAYED + MENUITEM "C&lose all", ID_CLOSEALL, GRAYED MENUITEM SEPARATOR - MENUITEM "Print Preview", ID_PRINTPRE, GRAYED - MENUITEM "Print...", ID_PRINT, GRAYED + MENUITEM "&Save", ID_SAVE, GRAYED + MENUITEM "Save &As...", ID_SAVEAS, GRAYED MENUITEM SEPARATOR - MENUITEM "Properties...", ID_PROP, GRAYED + MENUITEM "Print Pre&view", ID_PRINTPRE, GRAYED + MENUITEM "&Print...", ID_PRINT, GRAYED MENUITEM SEPARATOR - MENUITEM "E&xit", ID_EXIT + MENUITEM "Pr&operties...", ID_PROP, GRAYED + MENUITEM SEPARATOR + MENUITEM "E&xit\tAlt+F4", ID_EXIT END - POPUP "Edit" + POPUP "&Edit" BEGIN - MENUITEM "Undo", ID_UNDO, GRAYED - MENUITEM "Redo", ID_REDO, GRAYED + MENUITEM "&Undo", ID_UNDO, GRAYED + MENUITEM "&Redo", ID_REDO, GRAYED MENUITEM SEPARATOR - MENUITEM "Cut", ID_CUT, GRAYED - MENUITEM "Copy", ID_COPY, GRAYED - MENUITEM "Paste", ID_PASTE, GRAYED - MENUITEM "Paste as new image",ID_PASTENEWIMAGE, GRAYED + MENUITEM "Cu&t", ID_CUT, GRAYED + MENUITEM "&Copy", ID_COPY, GRAYED + MENUITEM "&Paste", ID_PASTE, GRAYED + MENUITEM "Paste as new &image", ID_PASTENEWIMAGE, GRAYED MENUITEM SEPARATOR - MENUITEM "Select All", ID_SELALL, GRAYED + MENUITEM "Select &All", ID_SELALL, GRAYED END - POPUP "View" + POPUP "&View" BEGIN - MENUITEM "Tools", ID_TOOLS, CHECKED - MENUITEM "Status Bar", ID_STATUSBAR, CHECKED + MENUITEM "&Tools", ID_TOOLS, CHECKED + MENUITEM "&Status Bar", ID_STATUSBAR, CHECKED END - POPUP "Image" + POPUP "&Image" BEGIN - MENUITEM "Crop", -1, GRAYED - MENUITEM "Resize", -1, GRAYED - MENUITEM "Rotate", -1, GRAYED - MENUITEM "Flip", -1, GRAYED - MENUITEM "Stretch", -1, GRAYED - MENUITEM "Skew", -1, GRAYED - MENUITEM "Invert Colours", -1, GRAYED + MENUITEM "&Crop...", -1, GRAYED + MENUITEM "&Resize...", -1, GRAYED + MENUITEM "R&otate...", -1, GRAYED + MENUITEM "&Flip...", -1, GRAYED + MENUITEM "&Stretch...", -1, GRAYED + MENUITEM "S&kew...", -1, GRAYED + MENUITEM "&Invert Colors", -1, GRAYED MENUITEM SEPARATOR - MENUITEM "Attributes", -1, GRAYED + MENUITEM "&Attributes...", -1, GRAYED END - POPUP "Colours" + POPUP "&Colors" BEGIN - MENUITEM "Edit Colours...", ID_EDITCOLOURS + MENUITEM "&Edit Colors...", ID_EDITCOLOURS END - POPUP "Window" + POPUP "&Window" BEGIN - MENUITEM "Tile", -1 - MENUITEM "Cascade", -1 + MENUITEM "&Cascade", ID_WINDOW_CASCADE + MENUITEM "Tile &Horizontally", ID_WINDOW_TILE_HORZ + MENUITEM "Tile &Vertiacally", ID_WINDOW_TILE_VERT + MENUITEM "&Arrange Icons", ID_WINDOW_ARRANGE + MENUITEM SEPARATOR + MENUITEM "Nex&t\tCtrl+F6", ID_WINDOW_NEXT END - POPUP "Help" + POPUP "&Help" BEGIN - MENUITEM "About...", ID_ABOUT + MENUITEM "&About...", ID_ABOUT END END @@ -108,14 +113,13 @@ END STRINGTABLE DISCARDABLE BEGIN + IDS_APPNAME "ImageSoft" IDS_LICENSE "This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.\r\n\r\nThis program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\r\n\r\nYou should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA." -END - -/* status bar info */ -STRINGTABLE DISCARDABLE -BEGIN - IDS_CURPOS "Cursor : %d,%d" - IDS_READY "Ready" + IDS_READY " Ready." + + IDS_TOOLBAR_STANDARD "Standard" + IDS_TOOLBAR_TEST "Test" + IDS_IMAGE_NAME "Image %1!u!" END /* Tooltips */ @@ -132,3 +136,18 @@ BEGIN IDS_TOOLTIP_UNDO "Undo" IDS_TOOLTIP_REDO "Redo" END + +/* Hints */ +STRINGTABLE DISCARDABLE +BEGIN + IDS_HINT_EXIT " Exits this application." + + IDS_HINT_SYS_RESTORE " Restores this window to normal size." + IDS_HINT_SYS_MOVE " Moves this window." + IDS_HINT_SYS_SIZE " Resizes this window." + IDS_HINT_SYS_MINIMIZE " Collapses this window to an icon." + IDS_HINT_SYS_MAXIMIZE " Expands this window to fill this screen." + IDS_HINT_SYS_CLOSE " Closes this window." + IDS_HINT_SYS_NEXT " Activates the next window." +END + diff --git a/reactos/base/applications/imagesoft/about.c b/reactos/base/applications/imagesoft/about.c index 9ebb069b236..145d750c675 100644 --- a/reactos/base/applications/imagesoft/about.c +++ b/reactos/base/applications/imagesoft/about.c @@ -1,11 +1,9 @@ -#include "imagesoft.h" - -extern HINSTANCE hInstance; +#include #ifdef _MSC_VER #pragma warning(disable : 4100) #endif -BOOL CALLBACK +INT_PTR CALLBACK AboutDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { HWND hLicenseEditWnd; diff --git a/reactos/base/applications/imagesoft/imagesoft.c b/reactos/base/applications/imagesoft/imagesoft.c index c1fb5d56155..a6198d8bf4d 100644 --- a/reactos/base/applications/imagesoft/imagesoft.c +++ b/reactos/base/applications/imagesoft/imagesoft.c @@ -1,787 +1,78 @@ -#include "imagesoft.h" - -#define ID_MDI_FIRSTCHILD 50000 - -const TCHAR AppClassName[] = _T("Parent"); -const TCHAR ChildClassName[] = _T("Child"); - +#include HINSTANCE hInstance; -HWND hMainWnd; -HWND hMDIClient; -HWND hStatus; -HWND hTool; -HWND hFloatTool; -HMENU hShortcutMenu; - -WORD cxClient; -WORD cyClient; - -/* - * Initialize the structure and send a message to the MDI - * frame requesting a new new child window. - */ -HWND CreateNewMDIChild(HWND hMDIClient) -{ - MDICREATESTRUCT mcs; - HWND hChild; - TCHAR Buf[15]; - static DWORD MDINum = 1; - DWORD style; - - _sntprintf(Buf, sizeof(Buf) / sizeof(TCHAR), _T("Untitled%d"), MDINum); - - style = 0;//MDIS_ALLCHILDSTYLES & ~WS_BORDER; - - mcs.szTitle = Buf; - mcs.szClass = ChildClassName; - mcs.hOwner = hInstance; - mcs.x = mcs.cx = CW_USEDEFAULT; - mcs.y = mcs.cy = CW_USEDEFAULT; - mcs.style = style; //MDIS_ALLCHILDSTYLES | WS_MAXIMIZE; - - hChild = (HWND)SendMessage(hMDIClient, WM_MDICREATE, 0, (LPARAM)&mcs); - if(!hChild) - { - MessageBox(hMDIClient, _T("MDI Child creation failed."), _T("Error!"), - MB_ICONEXCLAMATION | MB_OK); - return hChild; - } - - MDINum++; - return hChild; -} - - -/* - * Main program message handler - */ -LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - switch(msg) - { - case WM_CREATE: - { - CLIENTCREATESTRUCT ccs; - TBADDBITMAP tbab; - HMENU hMenu; - INT iImageOffset; - INT statwidths[] = {300, 450, 550, -1}; /* widths of status bar */ - TCHAR Buf[6]; - - /* Standard toolbar buttons */ - TBBUTTON StdButtons [NUM_BUTTONS] = - { - /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */ - {STD_FILENEW, ID_NEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0, 0}, /* new */ - {STD_FILEOPEN, ID_OPEN, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}, /* open */ - {STD_FILESAVE, ID_SAVE, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0}, /* save */ - - {10, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */ - - {STD_PRINTPRE, ID_PRINTPRE, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* print */ - {STD_PRINT, ID_PRINT, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* print preview */ - - {10, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */ - - {STD_CUT, ID_CUT, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* cut */ - {STD_COPY, ID_COPY, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* copy */ - {STD_PASTE, ID_PASTE, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* paste */ - - {10, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */ - - {STD_UNDO, ID_UNDO, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* undo */ - {STD_REDOW, ID_REDO, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* redo */ - - {10, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, - }; - - -/* ======================== Create Std Toolbar ============================== */ - - /* Create Toolbar */ - hTool = CreateWindowEx(0, - TOOLBARCLASSNAME, - NULL, - WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS, - 0, 0, 0, 0, - hwnd, - (HMENU)IDC_TOOLBAR, - hInstance, - NULL); - if(hTool == NULL) - MessageBox(hwnd, _T("Could not create tool bar."), _T("Error!"), MB_OK | MB_ICONERROR); - - /* Send the TB_BUTTONSTRUCTSIZE message, which is required for backward compatibility */ - SendMessage(hTool, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0); - - /* Add standard images */ - tbab.hInst = HINST_COMMCTRL; - tbab.nID = IDB_STD_SMALL_COLOR; - SendMessage(hTool, TB_ADDBITMAP, NUM_BUTTONS, (LPARAM)&tbab); - - /* Add buttons to toolbar */ - SendMessage(hTool, TB_ADDBUTTONS, NUM_BUTTONS, (LPARAM) &StdButtons); - - /* Show toolbar */ - ShowWindow(hTool, SW_SHOW); - - - -/* ======================== Create Floating Toolbar ============================== */ - - hFloatTool = CreateDialog(GetModuleHandle(NULL),MAKEINTRESOURCE(IDD_TOOLBAR), - hwnd, (DLGPROC)ToolDlgProc); - if(hFloatTool != NULL) - { - ;//ShowWindow(hFloatTool, SW_SHOW); - } - else - { - MessageBox(hwnd, _T("CreateDialog returned NULL"), _T("Warning!"), - MB_OK | MB_ICONINFORMATION); - } - - /* Send the TB_BUTTONSTRUCTSIZE message, which is required for backward compatibility */ - SendMessage(hFloatTool, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0); - - /* Add custom images */ - tbab.hInst = HINST_COMMCTRL; - tbab.nID = IDB_STD_SMALL_COLOR; - iImageOffset = (INT)SendMessage(hFloatTool, TB_ADDBITMAP, 10, (LPARAM)&tbab); - - /* StdButtons[0].iBitmap += iImageOffset; / * properties * / - StdButtons[1].iBitmap += iImageOffset; / * refresh * / - StdButtons[2].iBitmap += iImageOffset; / * export * / - StdButtons[4].iBitmap += iImageOffset; / * create * / - StdButtons[6].iBitmap += iImageOffset; / * start * / - StdButtons[7].iBitmap += iImageOffset; / * stop * / - StdButtons[8].iBitmap += iImageOffset; / * pause * / - StdButtons[9].iBitmap += iImageOffset; / * restart * / - StdButtons[11].iBitmap += iImageOffset; / * help * / - StdButtons[12].iBitmap += iImageOffset; / * exit * / -*/ - - /* Add buttons to toolbar */ - SendMessage(hFloatTool, TB_ADDBUTTONS, NUM_BUTTONS, (LPARAM) &StdButtons); - - /* Show toolbar */ - //ShowWindow(hFloatTool, SW_SHOWNORMAL); - - - -/* ======================== Create Status Bar ============================== */ - - hStatus = CreateWindowEx(0, - STATUSCLASSNAME, - NULL, - WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, - 0, 0, 0, 0, - hwnd, - (HMENU)IDC_STATUSBAR, - hInstance, - NULL); - if(hStatus == NULL) - MessageBox(hwnd, _T("Could not create status bar."), - _T("Error!"), MB_OK | MB_ICONERROR); - - SendMessage(hStatus, SB_SETPARTS, sizeof(statwidths)/sizeof(int), (LPARAM)statwidths); - - -/* ======================== Create Popup Menu ============================== */ - - hShortcutMenu = LoadMenu(hInstance, MAKEINTRESOURCE (IDR_POPUP)); - hShortcutMenu = GetSubMenu(hShortcutMenu, 0); - - -/* ======================= Create MDI Client ============================= */ - - /* Find window menu where children will be listed */ - ccs.hWindowMenu = GetSubMenu(GetMenu(hwnd), 5); - ccs.idFirstChild = ID_MDI_FIRSTCHILD; - - hMDIClient = CreateWindowEx(WS_EX_CLIENTEDGE, - _T("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(hMDIClient == NULL) - MessageBox(hwnd, _T("Could not create MDI client."), - _T("Error!"), MB_OK | MB_ICONERROR); - - -/* ======================= Miscelaneous ============================= */ - - hMenu = GetMenu(hwnd); - - EnableMenuItem(hMenu, 1, MF_DELETE); /* edit */ - EnableMenuItem(hMenu, 2, MF_REMOVE); /* image */ - EnableMenuItem(hMenu, 3, MF_BYPOSITION | MF_REMOVE); /* colours */ - EnableMenuItem(hMenu, 4, MF_BYPOSITION | MF_DELETE); /* window */ - - - /* indicate program is ready in the status bar */ - LoadString(hInstance, IDS_READY, Buf, sizeof(Buf) / sizeof(TCHAR)); - SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)Buf); - - /* inilalize file open/save structure */ - FileInitialize(hwnd); - - //Style = GetWindowLong(hwnd, GWL_STYLE); - - //SetWindowLong(hwnd, GWL_STYLE, (Style & DS_CENTER)); - - } - break; - - case WM_SIZE: - { - RECT rcTool; - int iToolHeight; - - RECT rcStatus; - int iStatusHeight; - - HWND hMDI; - int iMDIHeight; - RECT rcClient; - - cxClient = LOWORD(lParam); - cyClient = HIWORD(lParam); - - /* Size toolbar and get height */ - hTool = GetDlgItem(hwnd, IDC_TOOLBAR); - SendMessage(hTool, TB_AUTOSIZE, 0, 0); - - GetWindowRect(hTool, &rcTool); - iToolHeight = rcTool.bottom - rcTool.top; - - /* Size status bar and get height */ - hStatus = GetDlgItem(hwnd, IDC_STATUSBAR); - GetWindowRect(hStatus, &rcStatus); - iStatusHeight = rcStatus.bottom - rcStatus.top; - - /* Calculate remaining height and size for the MDI frame */ - GetClientRect(hwnd, &rcClient); - - iMDIHeight = rcClient.bottom - iToolHeight - iStatusHeight; - - hMDI = GetDlgItem(hwnd, IDC_MAIN_MDI); - SetWindowPos(hMDIClient, NULL, 0, iToolHeight, rcClient.right, iMDIHeight, SWP_NOZORDER); - } - break; - - case WM_NOTIFY: - { - NMHDR* nm = (NMHDR*) lParam; - - switch (nm->code) - { - case TTN_GETDISPINFO: - { - LPTOOLTIPTEXT lpttt; - UINT idButton; - - lpttt = (LPTOOLTIPTEXT) lParam; - - /* Specify the resource identifier of the descriptive - * text for the given button. */ - idButton = (UINT)lpttt->hdr.idFrom; - switch (idButton) - { - case ID_NEW: - lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_NEW); - break; - - case ID_OPEN: - lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_OPEN); - break; - - case ID_SAVE: - lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_SAVE); - break; - - case ID_PRINTPRE: - lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_PRINTPRE); - break; - - case ID_PRINT: - lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_PRINT); - break; - - case ID_CUT: - lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_CUT); - break; - - case ID_COPY: - lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_COPY); - break; - - case ID_PASTE: - lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_PASTE); - break; - - case ID_UNDO: - lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_UNDO); - break; - - case ID_REDO: - lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_REDO); - break; - - } - } - break; - - default: - break; - } - } - break; -/* - case WM_CONTEXTMENU: - { - int xPos, yPos; - - xPos = GET_X_LPARAM(lParam); - yPos = GET_Y_LPARAM(lParam); - - TrackPopupMenuEx(hShortcutMenu, TPM_RIGHTBUTTON, - xPos, yPos, hwnd, NULL); - } - break; -*/ - case WM_COMMAND: - - switch(LOWORD(wParam)) - { - case ID_NEW: - CreateNewMDIChild(hMDIClient); - break; - - case ID_OPEN: - DoOpenFile(hwnd); - break; - - case ID_SAVEAS: - DoSaveFile(hwnd); - break; - - case ID_CLOSE: - { - /* close the active child window */ - HWND hChild = (HWND)SendMessage(hMDIClient, WM_MDIGETACTIVE,0,0); - if(hChild) - { - SendMessage(hChild, WM_CLOSE, 0, 0); - } - } - break; - - case ID_CLOSEALL: - { - HWND hChild; - /* loop until all windows have been closed */ - while ((hChild = (HWND)SendMessage(hMDIClient, WM_MDIGETACTIVE,0,0)) != NULL) - { - SendMessage(hChild, WM_CLOSE, 0, 0); - } - } - break; - - case ID_TOOLS: - ShowHideToolbar(hFloatTool); - break; - - case ID_STATUSBAR: - ShowHideToolbar(hStatus); - /* FIXME: Need to resize client area */ - break; - - case ID_EXIT: - PostMessage(hwnd, WM_CLOSE, 0, 0); - break; - - case ID_EDITCOLOURS: - { - /* open up the colour selection dialog */ - - static CHOOSECOLOR cc; - static COLORREF crCustColors[16]; - - cc.lStructSize = sizeof(CHOOSECOLOR); - cc.hwndOwner = hwnd; - cc.hInstance = NULL; - cc.rgbResult = RGB(0x80, 0x80, 0x80); - cc.lpCustColors = crCustColors; - cc.Flags = CC_RGBINIT | CC_FULLOPEN; - cc.lCustData = 0; - cc.lpfnHook = NULL; - cc.lpTemplateName = NULL; - - ChooseColor(&cc); - } - break; - - case ID_WINDOW_TILE: - SendMessage(hMDIClient, WM_MDITILE, 0, 0); - break; - - case ID_WINDOW_CASCADE: - SendMessage(hMDIClient, WM_MDICASCADE, 0, 0); - break; - - case ID_ABOUT: - DialogBox(hInstance, - MAKEINTRESOURCE(IDD_ABOUTBOX), - hMainWnd, - (DLGPROC)AboutDialogProc); - break; - - default: - /* Catch all commands that I didn't process directly and do - * a check to see if the value is greater than or equal to - * ID_MDI_FIRSTCHILD. If it is, then the user has clicked - * on one of the Window menu items and we send the message - * on to DefFrameProc() for processing. - */ - if(LOWORD(wParam) >= ID_MDI_FIRSTCHILD) - DefFrameProc(hwnd, hMDIClient, WM_COMMAND, wParam, lParam); - else - { - HWND hChild = (HWND)SendMessage(hMDIClient, WM_MDIGETACTIVE,0,0); - if(hChild) - SendMessage(hChild, WM_COMMAND, wParam, lParam); - } - } - break; - - case WM_CLOSE: - DestroyMenu(hShortcutMenu); - DestroyWindow(hwnd); - break; - - case WM_DESTROY: - PostQuitMessage(0); - break; - - default: - return DefFrameProc(hwnd, hMDIClient, msg, wParam, lParam); - } - return 0; -} - - -void GetLargestDisplayMode (int * pcxBitmap, int * pcyBitmap) -{ - DEVMODE devmode ; - int iModeNum = 0 ; - - * pcxBitmap = * pcyBitmap = 0 ; - - ZeroMemory (&devmode, sizeof (DEVMODE)) ; - devmode.dmSize = sizeof (DEVMODE) ; - - while (EnumDisplaySettings (NULL, iModeNum++, &devmode)) - { - * pcxBitmap = max (* pcxBitmap, (int) devmode.dmPelsWidth) ; - * pcyBitmap = max (* pcyBitmap, (int) devmode.dmPelsHeight) ; - } -} - - - -/* - * MDI child window message handler - */ -LRESULT CALLBACK MDIChildWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - static BOOL fLeftButtonDown, fRightButtonDown; - static HBITMAP hBitmap; - static HDC hdcMem; - static INT cxBitmap, cyBitmap, cxClient, cyClient, xMouse, yMouse; - HDC hdc; - PAINTSTRUCT ps; - - switch(msg) - { - case WM_CREATE: - GetLargestDisplayMode(&cxBitmap, &cyBitmap); - - hdc = GetDC(hwnd); - hBitmap = CreateCompatibleBitmap(hdc, cxBitmap, cyBitmap); - hdcMem = CreateCompatibleDC(hdc); - ReleaseDC(hwnd, hdc); - - if (!hBitmap) // no memory for bitmap - { - DeleteDC(hdcMem); - return -1; - } - - SelectObject(hdcMem, hBitmap); - PatBlt(hdcMem, 0, 0, cxBitmap, cyBitmap, WHITENESS); - - break; - - case WM_MDIACTIVATE: - { - HMENU hMenu, hFileMenu; - UINT EnableFlag; - - hMenu = GetMenu(hMainWnd); - if(hwnd == (HWND)lParam) - { /* being activated, enable the menus */ - EnableFlag = MF_ENABLED; - } - else - { - TCHAR Buf[6]; - /* being de-activated, gray the menus */ - EnableFlag = MF_GRAYED; - - /* indicate program is ready in the status bar */ - LoadString(hInstance, IDS_READY, Buf, sizeof(Buf) / sizeof(TCHAR)); - SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)Buf); - } - - EnableMenuItem(hMenu, 1, MF_BYPOSITION | EnableFlag); /* edit */ - EnableMenuItem(hMenu, 2, MF_BYPOSITION | EnableFlag); /* image */ - EnableMenuItem(hMenu, 3, MF_BYPOSITION | EnableFlag); /* colours */ - EnableMenuItem(hMenu, 4, MF_BYPOSITION | EnableFlag); /* window */ - - hFileMenu = GetSubMenu(hMenu, 0); - EnableMenuItem(hFileMenu, ID_SAVEAS, MF_BYCOMMAND | EnableFlag); - - EnableMenuItem(hFileMenu, ID_CLOSE, MF_BYCOMMAND | EnableFlag); - EnableMenuItem(hFileMenu, ID_CLOSEALL, MF_BYCOMMAND | EnableFlag); - - SendMessage(hTool, TB_SETSTATE, ID_COPY, - (LPARAM)MAKELONG(TBSTATE_ENABLED, 0)); - - DrawMenuBar(hMainWnd); - } - break; - - case WM_NOTIFY: - { - MSG mymsg; - PeekMessage(&mymsg, NULL, 0, 0, PM_REMOVE); - } - break; - - case WM_MOUSEMOVE: - { - POINT pt; - TCHAR Buf[200]; - TCHAR Cur[15]; - - pt.x = LOWORD(lParam); - pt.y = HIWORD(lParam); - - /* set cursor location in the status bar */ - LoadString(hInstance, IDS_CURPOS, Cur, sizeof(Cur) / sizeof(TCHAR)); - _sntprintf(Buf, sizeof(Buf) / sizeof(TCHAR), Cur, pt.x, pt.y); - SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)Buf); - - /* change cursor to a cross */ - /*FIXME: can this be forced into the MDI child class? */ - SetCursor (LoadCursor (NULL, IDC_CROSS)); - - if (!fLeftButtonDown && !fRightButtonDown) - break; - - hdc = GetDC(hwnd); - - SelectObject(hdc, - GetStockObject(fLeftButtonDown ? BLACK_PEN : WHITE_PEN) ); - - SelectObject(hdcMem, - GetStockObject(fLeftButtonDown ? BLACK_PEN : WHITE_PEN) ); - - MoveToEx (hdc, xMouse, yMouse, NULL); - MoveToEx (hdcMem, xMouse, yMouse, NULL); - - xMouse = (short) LOWORD(lParam); - yMouse = (short) HIWORD(lParam); - - LineTo(hdc, xMouse, yMouse); - LineTo(hdcMem, xMouse, yMouse); - - ReleaseDC(hwnd, hdc); - } - break; - - case WM_LBUTTONDOWN: - if (!fRightButtonDown) - SetCapture(hwnd); - - xMouse = LOWORD(lParam); - yMouse = HIWORD(lParam); - fLeftButtonDown = TRUE; - break; - - case WM_LBUTTONUP: - if (fLeftButtonDown) - SetCapture(NULL); - - fLeftButtonDown = FALSE; - break; - - case WM_RBUTTONDOWN: - if (!fLeftButtonDown) - SetCapture(hwnd); - - xMouse = LOWORD(lParam); - yMouse = HIWORD(lParam); - fRightButtonDown = TRUE; - break; - - case WM_RBUTTONUP: - if (fRightButtonDown) - SetCapture(NULL); - - fRightButtonDown = FALSE; - break; - - case WM_PAINT: - hdc = BeginPaint(hwnd, &ps); - - BitBlt(hdc, 0, 0, cxClient, cyClient, hdcMem, 0, 0, SRCCOPY); - - EndPaint(hwnd, &ps); - break; - - case WM_SIZE: - - - return DefMDIChildProc(hwnd, msg, wParam, lParam); - - case WM_DESTROY: - DeleteDC(hdcMem); - DeleteObject(hBitmap); - break; - - - default: - { - TCHAR Buf[6]; - - /* indicate program is ready in the status bar */ - LoadString(hInstance, IDS_READY, Buf, sizeof(Buf) / sizeof(TCHAR)); - SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)Buf); - - return DefMDIChildProc(hwnd, msg, wParam, lParam); - } - - } - return 0; -} - -/* - * Register the MDI child window class - */ -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, IDI_APPLICATION); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); - wc.lpszMenuName = NULL; - wc.lpszClassName = ChildClassName; - wc.hIconSm = (HICON)LoadImage(hInstance, - MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, 0); - - if(!RegisterClassEx(&wc)) - { - MessageBox(0, _T("Could Not Register Child Window"), _T("Error!"), - MB_ICONEXCLAMATION | MB_OK); - return FALSE; - } - else - return TRUE; -} +HANDLE ProcessHeap; #ifdef _MSC_VER #pragma warning(disable : 4100) #endif -int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance, - LPSTR lpCmdLine, int nCmdShow) +int WINAPI +WinMain(HINSTANCE hThisInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nCmdShow) { - WNDCLASSEX wc; + LPTSTR lpAppName; + HWND hMainWnd; MSG Msg; + BOOL bRet; + int Ret = 1; INITCOMMONCONTROLSEX icex; hInstance = hThisInstance; + ProcessHeap = GetProcessHeap(); icex.dwSize = sizeof(INITCOMMONCONTROLSEX); - icex.dwICC = ICC_BAR_CLASSES; + icex.dwICC = ICC_BAR_CLASSES | ICC_COOL_CLASSES; InitCommonControlsEx(&icex); - wc.cbSize = sizeof(WNDCLASSEX); - wc.style = 0; - wc.lpfnWndProc = WndProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = hInstance; - wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON)); - wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); - wc.lpszMenuName = MAKEINTRESOURCE(IDR_MAINMENU); - wc.lpszClassName = AppClassName; - wc.hIconSm = (HICON)LoadImage(hInstance, - MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, 0); - - if(!RegisterClassEx(&wc)) + if (!AllocAndLoadString(&lpAppName, + hInstance, + IDS_APPNAME)) { - MessageBox(NULL, _T("Window Registration Failed!"), _T("Error!"), - MB_ICONEXCLAMATION | MB_OK); - return 0; + return 1; } - if(!SetUpMDIChildWindowClass(hInstance)) - return 0; - - hMainWnd = CreateWindowEx(0, - AppClassName, - _T("ImageSoft"), - WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, - CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, - NULL, NULL, hInstance, NULL); - - if(hMainWnd == NULL) + if (TbdInitImpl()) { - MessageBox(NULL, _T("Window Creation Failed!"), _T("Error!"), - MB_ICONEXCLAMATION | MB_OK); - return 0; - } - - ShowWindow(hMainWnd, nCmdShow); - UpdateWindow(hMainWnd); - - while( GetMessage( &Msg, NULL, 0, 0 ) ) - { - if (!TranslateMDISysAccel(hMDIClient, &Msg)) + if (InitMainWindowImpl()) { - TranslateMessage(&Msg); - DispatchMessage(&Msg); + if (InitImageEditWindowImpl()) + { + hMainWnd = CreateMainWindow(lpAppName, + nCmdShow); + if (hMainWnd != NULL) + { + /* pump the message queue */ + while((bRet = GetMessage(&Msg, + NULL, + 0, + 0) != 0)) + { + if (bRet != (BOOL)-1) + { + if (!MainWndTranslateMDISysAccel(hMainWnd, + &Msg)) + { + TranslateMessage(&Msg); + DispatchMessage(&Msg); + } + } + } + + Ret = 0; + } + + UninitImageEditWindowImpl(); + } + + UninitMainWindowImpl(); } + + TbdUninitImpl(); } - return (int)Msg.wParam; + + LocalFree((HLOCAL)lpAppName); + + return Ret; } diff --git a/reactos/base/applications/imagesoft/imagesoft.h b/reactos/base/applications/imagesoft/imagesoft.h deleted file mode 100644 index 90f3584a05d..00000000000 --- a/reactos/base/applications/imagesoft/imagesoft.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef __PAINT_H -#define __PAINT_H - -//#define WIN32_LEAN_AND_MEAN -#include -#include /* GET_X/Y_LPARAM */ -#include -#include -#include -#include "resource.h" - -#define MAX_KEY_LENGTH 256 -#define NUM_BUTTONS 14 - -BOOL CALLBACK AboutDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); -BOOL CALLBACK ToolDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam); - -BOOL ShowHideToolbar(HWND hwnd); - -VOID FileInitialize(HWND hwnd); -VOID DoOpenFile(HWND hwnd); -VOID DoSaveFile(HWND hwnd); - -#endif /* __SERVMAN_H */ diff --git a/reactos/base/applications/imagesoft/imagesoft.rbuild b/reactos/base/applications/imagesoft/imagesoft.rbuild index 7b5771e9a37..098e51b574e 100644 --- a/reactos/base/applications/imagesoft/imagesoft.rbuild +++ b/reactos/base/applications/imagesoft/imagesoft.rbuild @@ -1,28 +1,31 @@ - - . - - - - - 0x600 - 0x501 - kernel32 - gdi32 - user32 - advapi32 - version - comctl32 - shell32 - comdlg32 - - about.c - floattoolbar.c - imagesoft.c - opensave.c - - imagesoft.rc - imagesoft.h - + + . + + + + 0x0600 + 0x0501 + ntdll + kernel32 + gdi32 + user32 + advapi32 + version + comctl32 + shell32 + comdlg32 + + about.c + imagesoft.c + imgedwnd.c + mainwnd.c + opensave.c + tooldock.c + misc.c + + imagesoft.rc + precomp.h + diff --git a/reactos/base/applications/imagesoft/imagesoft.rc b/reactos/base/applications/imagesoft/imagesoft.rc index bae7340d263..1a5bb48645b 100644 --- a/reactos/base/applications/imagesoft/imagesoft.rc +++ b/reactos/base/applications/imagesoft/imagesoft.rc @@ -9,6 +9,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +1 24 DISCARDABLE "manifest.xml" + IDI_ICON ICON "res/imagesoft.ico" #include "En.rc" diff --git a/reactos/base/applications/imagesoft/imgedwnd.c b/reactos/base/applications/imagesoft/imgedwnd.c new file mode 100644 index 00000000000..9939d898025 --- /dev/null +++ b/reactos/base/applications/imagesoft/imgedwnd.c @@ -0,0 +1,296 @@ +#include + +static const TCHAR szImageEditWndClass[] = TEXT("ImageSoftEditWndClass"); + +#define IMAGE_FRAME_SIZE 1 + +static VOID +EditWndUpdateScrollInfo(PEDIT_WND_INFO Info) +{ + SCROLLINFO si; + RECT rcClient; + + GetClientRect(Info->hSelf, + &rcClient); + + si.cbSize = sizeof(si); + si.fMask = SIF_PAGE | SIF_RANGE; + si.nPage = rcClient.right - (2 * IMAGE_FRAME_SIZE); + si.nMin = 0; + si.nMax = Info->Width; + + SetScrollInfo(Info->hSelf, + SB_HORZ, + &si, + TRUE); + + si.nPage = rcClient.bottom - (2 * IMAGE_FRAME_SIZE); + si.nMax = Info->Height; + SetScrollInfo(Info->hSelf, + SB_VERT, + &si, + TRUE); +} + +static BOOL +InitEditWnd(PEDIT_WND_INFO Info) +{ + Info->Zoom = 100; + + if (Info->OpenInfo != NULL) + { + if (Info->OpenInfo->CreateNew) + { + Info->Width = Info->OpenInfo->New.Width; + Info->Height = Info->OpenInfo->New.Height; + } + else + { + /* Load the image from file */ + } + + Info->OpenInfo = NULL; + } + + EditWndUpdateScrollInfo(Info); + + /* Add image editor to the list */ + Info->Next = Info->MainWnd->ImageEditors; + Info->MainWnd->ImageEditors = Info; + + /* FIXME - if returning FALSE, remove the image editor from the list! */ + return TRUE; +} + +static VOID +DestroyEditWnd(PEDIT_WND_INFO Info) +{ + PEDIT_WND_INFO *PrevEditor; + PEDIT_WND_INFO Editor; + + /* FIXME - free resources and run down editor */ + + /* Remove the image editor from the list */ + PrevEditor = &Info->MainWnd->ImageEditors; + Editor = Info->MainWnd->ImageEditors; + do + { + if (Editor == Info) + { + *PrevEditor = Info->Next; + break; + } + PrevEditor = &Editor->Next; + Editor = Editor->Next; + } while (Editor != NULL); +} + +static VOID +ImageEditWndRepaint(PEDIT_WND_INFO Info, + HDC hDC, + LPPAINTSTRUCT lpps) +{ + /* FIXME */ +} + +static LRESULT CALLBACK +ImageEditWndProc(HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + PEDIT_WND_INFO Info; + LRESULT Ret = 0; + + /* Get the window context */ + Info = (PEDIT_WND_INFO)GetWindowLongPtr(hwnd, + GWLP_USERDATA); + if (Info == NULL && uMsg != WM_CREATE) + { + goto HandleDefaultMessage; + } + + switch (uMsg) + { + case WM_ERASEBKGND: + if (Info->Width != 0 && Info->Height != 0) + { + Ret = TRUE; + } + break; + + case WM_PAINT: + { + if (Info->Width != 0 && Info->Height != 0) + { + PAINTSTRUCT ps; + HDC hDC; + + hDC = BeginPaint(hwnd, + &ps); + if (hDC != NULL) + { + ImageEditWndRepaint(Info, + hDC, + &ps); + + EndPaint(hwnd, + &ps); + } + } + break; + } + + case WM_SIZE: + { + EditWndUpdateScrollInfo(Info); + goto HandleDefaultMessage; + } + + case WM_MENUSELECT: + case WM_ENTERMENULOOP: + case WM_EXITMENULOOP: + /* forward these messages to the main window procedure */ + Ret = SendMessage(Info->MainWnd->hSelf, + uMsg, + wParam, + lParam); + break; + + case WM_MDIACTIVATE: + /* Switch the main window context if neccessary */ + MainWndSwitchEditorContext(Info->MainWnd, + (HWND)wParam, + (HWND)lParam); + break; + + case WM_CREATE: + { + Info = (PEDIT_WND_INFO)(((LPMDICREATESTRUCT)((LPCREATESTRUCT)lParam)->lpCreateParams)->lParam); + Info->hSelf = hwnd; + + SetWindowLongPtr(hwnd, + GWLP_USERDATA, + (LONG_PTR)Info); + + if (!InitEditWnd(Info)) + { + Ret = (LRESULT)-1; + break; + } + break; + } + + case WM_DESTROY: + { + DestroyEditWnd(Info); + + HeapFree(ProcessHeap, + 0, + Info); + SetWindowLongPtr(hwnd, + GWLP_USERDATA, + 0); + break; + } + + default: +HandleDefaultMessage: + Ret = DefMDIChildProc(hwnd, + uMsg, + wParam, + lParam); + break; + } + + return Ret; +} + +VOID +SetImageEditorEnvironment(PEDIT_WND_INFO Info, + BOOL Setup) +{ + if (Setup) + { + /* FIXME - setup editor environment (e.g. show toolbars, enable menus etc) */ + } + else + { + /* FIXME - cleanup editor environment (e.g. hide toolbars, disable menus etc) */ + } +} + +BOOL +CreateImageEditWindow(struct _MAIN_WND_INFO *MainWnd, + LPCTSTR lpCaption, + POPEN_IMAGE_EDIT_INFO OpenInfo) +{ + PEDIT_WND_INFO Info; + HWND hWndEditor; + + Info = HeapAlloc(ProcessHeap, + 0, + sizeof(EDIT_WND_INFO)); + if (Info != NULL) + { + ZeroMemory(Info, + sizeof(EDIT_WND_INFO)); + Info->MainWnd = MainWnd; + Info->MdiEditorType = metImageEditor; + Info->OpenInfo = OpenInfo; + + hWndEditor = CreateMDIWindow(szImageEditWndClass, + lpCaption, + WS_HSCROLL | WS_VSCROLL, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + MainWnd->hMdiClient, + hInstance, + (LPARAM)Info); + + if (hWndEditor != NULL) + { + return TRUE; + } + + HeapFree(ProcessHeap, + 0, + Info); + } + + return FALSE; +} + +BOOL +InitImageEditWindowImpl(VOID) +{ + WNDCLASSEX wc = {0}; + + wc.cbSize = sizeof(WNDCLASSEX); + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = ImageEditWndProc; + wc.hInstance = hInstance; + wc.hIcon = LoadIcon(hInstance, + MAKEINTRESOURCE(IDI_ICON)); + wc.hCursor = LoadCursor(NULL, + IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); + wc.lpszClassName = szImageEditWndClass; + wc.hIconSm = (HICON)LoadImage(hInstance, + MAKEINTRESOURCE(IDI_ICON), + IMAGE_ICON, + 16, + 16, + LR_SHARED); + + return RegisterClassEx(&wc) != (ATOM)0; +} + +VOID +UninitImageEditWindowImpl(VOID) +{ + UnregisterClass(szImageEditWndClass, + hInstance); +} diff --git a/reactos/base/applications/imagesoft/mainwnd.c b/reactos/base/applications/imagesoft/mainwnd.c new file mode 100644 index 00000000000..8bc8dd1d064 --- /dev/null +++ b/reactos/base/applications/imagesoft/mainwnd.c @@ -0,0 +1,905 @@ +#include + +static const TCHAR szMainWndClass[] = TEXT("ImageSoftWndClass"); + +#define ID_MDI_FIRSTCHILD 50000 +#define ID_MDI_WINDOWMENU 5 + +/* menu hints */ +static const MENU_HINT MainMenuHintTable[] = { + /* File Menu */ + {ID_CLOSE, IDS_HINT_SYS_CLOSE}, + {ID_EXIT, IDS_HINT_EXIT}, + + /* Window Menu */ + {ID_WINDOW_NEXT, IDS_HINT_SYS_NEXT} +}; + +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_SYS_CLOSE}, + {SC_NEXTWINDOW, IDS_HINT_SYS_NEXT}, +}; + +/* Standard Toolbar */ +#define ID_TOOLBAR_STANDARD 0 +static const TCHAR szToolbarStandard[] = TEXT("STANDARD"); +static const TBBUTTON StdButtons[] = { + /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */ + {STD_FILENEW, ID_NEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0, 0}, /* new */ + {STD_FILEOPEN, ID_OPEN, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}, /* open */ + {STD_FILESAVE, ID_SAVE, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0}, /* save */ + + {10, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */ + + {STD_PRINTPRE, ID_PRINTPRE, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* print */ + {STD_PRINT, ID_PRINT, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* print preview */ + + {10, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */ + + {STD_CUT, ID_CUT, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* cut */ + {STD_COPY, ID_COPY, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* copy */ + {STD_PASTE, ID_PASTE, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* paste */ + + {10, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, /* separator */ + + {STD_UNDO, ID_UNDO, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* undo */ + {STD_REDOW, ID_REDO, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0 }, /* redo */ + + {10, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0}, +}; + +/* Test Toolbar */ +#define ID_TOOLBAR_TEST 1 +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}, +}; + +static BOOL CALLBACK +MainWndCreateToolbarClient(struct _TOOLBAR_DOCKS *TbDocks, + const DOCKBAR *Dockbar, + PVOID Context, + HWND hParent, + HWND *hwnd) +{ + const TBBUTTON *Buttons = NULL; + UINT NumButtons = 0; + HWND hWndClient = NULL; + + UNREFERENCED_PARAMETER(Context); + + /* Standard toolbar */ + switch (Dockbar->BarId) + { + case ID_TOOLBAR_STANDARD: + { + Buttons = StdButtons; + NumButtons = sizeof(StdButtons) / sizeof(StdButtons[0]); + break; + } + + case ID_TOOLBAR_TEST: + { + hWndClient = CreateWindowEx(0, + TEXT("BUTTON"), + TEXT("Test Button"), + WS_CHILD | WS_VISIBLE, + 0, + 0, + 150, + 25, + hParent, + NULL, + hInstance, + NULL); + break; + } + } + + if (Buttons != NULL) + { + TBADDBITMAP tbab; + + 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) + { + SendMessage(hWndClient, + TB_SETEXTENDEDSTYLE, + 0, + TBSTYLE_EX_HIDECLIPPEDBUTTONS); + + /* Send the TB_BUTTONSTRUCTSIZE message, which is required for backward compatibility */ + SendMessage(hWndClient, + TB_BUTTONSTRUCTSIZE, + sizeof(Buttons[0]), + 0); + + /* Add standard images */ + tbab.hInst = HINST_COMMCTRL; + tbab.nID = IDB_STD_SMALL_COLOR; + SendMessage(hWndClient, + TB_ADDBITMAP, + (WPARAM)NumButtons, + (LPARAM)&tbab); + + /* Add buttons to toolbar */ + SendMessage(hWndClient, + TB_ADDBUTTONS, + (WPARAM)NumButtons, + (LPARAM)Buttons); + } + } + + 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_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 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_STANDARD: + { + SIZE Size; + BOOL Vert; + DWORD dwStyle = 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); + + 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 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); + } +} + +static VOID CALLBACK +MainWndResize(PVOID Context, + WORD cx, + WORD 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; + + /* 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); + + /* 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); +} + +static VOID +MainWndCommand(PMAIN_WND_INFO Info, + WORD CmdId, + HWND hControl) +{ + UNREFERENCED_PARAMETER(hControl); + + switch (CmdId) + { + /* File Menu */ + case ID_NEW: + { + OPEN_IMAGE_EDIT_INFO OpenInfo; + LPTSTR lpCaption = NULL; + + LoadAndFormatString(hInstance, + IDS_IMAGE_NAME, + &lpCaption, + ++Info->ImagesCreated); + + OpenInfo.CreateNew = TRUE; + OpenInfo.New.Width = 400; + OpenInfo.New.Height = 300; + + CreateImageEditWindow(Info, + lpCaption, + &OpenInfo); + + if (lpCaption != NULL) + LocalFree((HLOCAL)lpCaption); + 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 */ +} + + +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; + + /* 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 */ + break; + } + + case WM_NOTIFY: + { + if (!TbdHandleNotifications(&Info->ToolDocks, + (LPNMHDR)lParam, + &Ret)) + { + /* FIXME - handle other notifications */ + } + 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_READY)) + { + MainWndMenuHint(Info, + LOWORD(wParam), + SystemMenuHintTable, + sizeof(SystemMenuHintTable) / sizeof(SystemMenuHintTable[0]), + IDS_READY); + } + } + 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_ACTIVATEAPP: + { + //TbdShowFloatingToolbars(&Info->ToolDocks, + // (BOOL)wParam); + break; + } + + 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); + 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_ICON)); + 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_ICON), + IMAGE_ICON, + 16, + 16, + LR_SHARED); + + return RegisterClassEx(&wc) != (ATOM)0; +} + +VOID +UninitMainWindowImpl(VOID) +{ + UnregisterClass(szMainWndClass, + hInstance); +} diff --git a/reactos/base/applications/imagesoft/manifest.xml b/reactos/base/applications/imagesoft/manifest.xml new file mode 100644 index 00000000000..8807ca4fdaa --- /dev/null +++ b/reactos/base/applications/imagesoft/manifest.xml @@ -0,0 +1,24 @@ + + + + ReactOS VMware(r) SVGA driver Installer + + + + + + + + diff --git a/reactos/base/applications/imagesoft/misc.c b/reactos/base/applications/imagesoft/misc.c new file mode 100644 index 00000000000..3d8ea5c926e --- /dev/null +++ b/reactos/base/applications/imagesoft/misc.c @@ -0,0 +1,160 @@ +#include + +static INT +LengthOfStrResource(IN HINSTANCE hInst, + IN UINT uID) +{ + HRSRC hrSrc; + HGLOBAL hRes; + LPWSTR lpName, lpStr; + + if (hInst == NULL) + { + return -1; + } + + /* There are always blocks of 16 strings */ + lpName = (LPWSTR)MAKEINTRESOURCE((uID >> 4) + 1); + + /* Find the string table block */ + if ((hrSrc = FindResourceW(hInst, lpName, (LPWSTR)RT_STRING)) && + (hRes = LoadResource(hInst, hrSrc)) && + (lpStr = LockResource(hRes))) + { + UINT x; + + /* Find the string we're looking for */ + uID &= 0xF; /* position in the block, same as % 16 */ + for (x = 0; x < uID; x++) + { + lpStr += (*lpStr) + 1; + } + + /* Found the string */ + return (int)(*lpStr); + } + return -1; +} + +INT +AllocAndLoadString(OUT LPTSTR *lpTarget, + IN HINSTANCE hInst, + IN UINT uID) +{ + INT ln; + + ln = LengthOfStrResource(hInst, + uID); + if (ln++ > 0) + { + (*lpTarget) = (LPWSTR)LocalAlloc(LMEM_FIXED, + ln * sizeof(TCHAR)); + if ((*lpTarget) != NULL) + { + INT Ret; + if (!(Ret = LoadString(hInst, uID, *lpTarget, ln))) + { + LocalFree((HLOCAL)(*lpTarget)); + } + return Ret; + } + } + return 0; +} + +DWORD +LoadAndFormatString(IN HINSTANCE hInstance, + IN UINT uID, + OUT LPTSTR *lpTarget, + ...) +{ + DWORD Ret = 0; + LPTSTR lpFormat; + va_list lArgs; + + if (AllocAndLoadString(&lpFormat, + hInstance, + uID) > 0) + { + va_start(lArgs, lpTarget); + /* let's use FormatMessage to format it because it has the ability to allocate + memory automatically */ + Ret = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING, + lpFormat, + 0, + 0, + (LPTSTR)lpTarget, + 0, + &lArgs); + va_end(lArgs); + + LocalFree((HLOCAL)lpFormat); + } + + return Ret; +} + +BOOL +StatusBarLoadAndFormatString(IN HWND hStatusBar, + IN INT PartId, + IN HINSTANCE hInstance, + IN UINT uID, + ...) +{ + BOOL Ret = FALSE; + LPTSTR lpFormat, lpStr; + va_list lArgs; + + if (AllocAndLoadString(&lpFormat, + hInstance, + uID) > 0) + { + va_start(lArgs, uID); + /* let's use FormatMessage to format it because it has the ability to allocate + memory automatically */ + Ret = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING, + lpFormat, + 0, + 0, + (LPTSTR)&lpStr, + 0, + &lArgs); + va_end(lArgs); + + if (lpStr != NULL) + { + Ret = (BOOL)SendMessage(hStatusBar, + SB_SETTEXT, + (WPARAM)PartId, + (LPARAM)lpStr); + LocalFree((HLOCAL)lpStr); + } + + LocalFree((HLOCAL)lpFormat); + } + + return Ret; +} + +BOOL +StatusBarLoadString(IN HWND hStatusBar, + IN INT PartId, + IN HINSTANCE hInstance, + IN UINT uID) +{ + BOOL Ret = FALSE; + LPTSTR lpStr; + + if (AllocAndLoadString(&lpStr, + hInstance, + uID) > 0) + { + Ret = (BOOL)SendMessage(hStatusBar, + SB_SETTEXT, + (WPARAM)PartId, + (LPARAM)lpStr); + LocalFree((HLOCAL)lpStr); + } + + return Ret; +} diff --git a/reactos/base/applications/imagesoft/opensave.c b/reactos/base/applications/imagesoft/opensave.c index ee0db016209..345e7332917 100644 --- a/reactos/base/applications/imagesoft/opensave.c +++ b/reactos/base/applications/imagesoft/opensave.c @@ -1,4 +1,4 @@ -#include "imagesoft.h" +#include static OPENFILENAME ofn; diff --git a/reactos/base/applications/imagesoft/precomp.h b/reactos/base/applications/imagesoft/precomp.h new file mode 100644 index 00000000000..3071eca5fca --- /dev/null +++ b/reactos/base/applications/imagesoft/precomp.h @@ -0,0 +1,255 @@ +#ifndef __IMAGESOFT_PRECOMP_H +#define __IMAGESOFT_PRECOMP_H + +//#define WIN32_LEAN_AND_MEAN +#include +#include /* GET_X/Y_LPARAM */ +#include +#include +#include +#include "resource.h" + +/* FIXME - add to headers !!! */ +#ifndef SB_SIMPLEID +#define SB_SIMPLEID 0xFF +#endif +#ifndef RBBS_USECHEVRON +#define RBBS_USECHEVRON 0x200 +#endif +#ifndef RBN_CHEVRONPUSHED +#define RBN_CHEVRONPUSHED (RBN_FIRST - 10) +#endif +ULONG DbgPrint(PCH Format,...); + +#define MAX_KEY_LENGTH 256 +#define NUM_BUTTONS 14 + +/* generic definitions and forward declarations */ +struct _MAIN_WND_INFO; +struct _EDIT_WND_INFO; + +typedef enum _MDI_EDITOR_TYPE { + metUnknown = 0, + metImageEditor, +} MDI_EDITOR_TYPE, *PMDI_EDITOR_TYPE; + +/* about.c */ +INT_PTR CALLBACK AboutDialogProc(HWND hDlg, + UINT message, + WPARAM wParam, + LPARAM lParam); + +/* imagesoft.c */ +extern HINSTANCE hInstance; +extern HANDLE ProcessHeap; + +/* imgedwnd.c */ +typedef struct _OPEN_IMAGE_EDIT_INFO +{ + BOOL CreateNew; + union + { + struct + { + LONG Width; + LONG Height; + } New; + struct + { + LPCTSTR lpFileName; + } Open; + }; +} OPEN_IMAGE_EDIT_INFO, *POPEN_IMAGE_EDIT_INFO; + +typedef struct _EDIT_WND_INFO +{ + MDI_EDITOR_TYPE MdiEditorType; /* Must be first member! */ + + HWND hSelf; + struct _MAIN_WND_INFO *MainWnd; + struct _EDIT_WND_INFO *Next; + POINT ScrollPos; + USHORT Zoom; + + POPEN_IMAGE_EDIT_INFO OpenInfo; /* Only valid during initialization */ + + /* Bitmap size */ + LONG Width; + LONG Height; +} EDIT_WND_INFO, *PEDIT_WND_INFO; + +BOOL CreateImageEditWindow(struct _MAIN_WND_INFO *MainWnd, + LPCTSTR lpCaption, + POPEN_IMAGE_EDIT_INFO OpenInfo); +VOID SetImageEditorEnvironment(PEDIT_WND_INFO Info, + BOOL Setup); +BOOL InitImageEditWindowImpl(VOID); +VOID UninitImageEditWindowImpl(VOID); + +/* tooldock.c */ + +typedef enum +{ + TOP_DOCK = 0, + LEFT_DOCK, + RIGHT_DOCK, + BOTTOM_DOCK, + NO_DOCK +} DOCK_POSITION; + +typedef struct _DOCKBAR +{ + UINT BarId; + LPCTSTR lpName; + UINT DisplayTextId; + DOCK_POSITION Position; +} DOCKBAR, *PDOCKBAR; + +struct _TOOLBAR_DOCKS; + +typedef BOOL (CALLBACK *PDOCKBAR_CREATECLIENT)(struct _TOOLBAR_DOCKS *TbDocks, + const DOCKBAR *Dockbar, + PVOID Context, + HWND hParent, + HWND *hwnd); +typedef BOOL (CALLBACK *PDOCKBAR_DESTROYCLIENT)(struct _TOOLBAR_DOCKS *TbDocks, + const DOCKBAR *Dockbar, + PVOID Context, + HWND hwnd); +typedef BOOL (CALLBACK *PDOCKBAR_INSERTBAND)(struct _TOOLBAR_DOCKS *TbDocks, + const DOCKBAR *Dockbar, + PVOID Context, + UINT *Index, + LPREBARBANDINFO rbi); +typedef VOID (CALLBACK *PDOCKBAR_DOCKBAND)(struct _TOOLBAR_DOCKS *TbDocks, + const DOCKBAR *Dockbar, + PVOID Context, + DOCK_POSITION DockFrom, + DOCK_POSITION DockTo, + LPREBARBANDINFO rbi); +typedef VOID (CALLBACK *PDOCKBAR_CHEVRONPUSHED)(struct _TOOLBAR_DOCKS *TbDocks, + const DOCKBAR *Dockbar, + PVOID Context, + HWND hwndChild, + LPNMREBARCHEVRON lpnm); + +typedef struct _DOCKBAR_ITEM_CALLBACKS +{ + PDOCKBAR_CREATECLIENT CreateClient; + PDOCKBAR_DESTROYCLIENT DestroyClient; + PDOCKBAR_INSERTBAND InsertBand; + PDOCKBAR_DOCKBAND DockBand; + PDOCKBAR_CHEVRONPUSHED ChevronPushed; +} DOCKBAR_ITEM_CALLBACKS, *PDOCKBAR_ITEM_CALLBACKS; + +typedef struct _DOCKBAR_ITEM +{ + struct _DOCKBAR_ITEM *Next; + DOCKBAR DockBar; + PVOID Context; + HWND hWndTool; + HWND hWndClient; + DOCK_POSITION PrevDock; + UINT PrevBandIndex; + const DOCKBAR_ITEM_CALLBACKS *Callbacks; +} DOCKBAR_ITEM, *PDOCKBAR_ITEM; + +typedef VOID (CALLBACK *PDOCKBAR_PARENTRESIZE)(PVOID Context, + WORD cx, + WORD cy); + +#define DOCKS_COUNT 4 +typedef struct _TOOLBAR_DOCKS +{ + HWND hParent; + PVOID Context; + HWND hRebar[DOCKS_COUNT]; + RECT rcRebar[DOCKS_COUNT]; + RECT rcClient; + PDOCKBAR_ITEM Items; + PDOCKBAR_PARENTRESIZE ParentResize; + PDOCKBAR_ITEM Dragging; + UINT DraggingBandId; + TCHAR szTempText[255]; +} TOOLBAR_DOCKS, *PTOOLBAR_DOCKS; + +VOID TbdInitializeDocks(PTOOLBAR_DOCKS TbDocks, + HWND hWndParent, + PVOID Context, + PDOCKBAR_PARENTRESIZE ParentResizeProc); +INT TbdAdjustUpdateClientRect(PTOOLBAR_DOCKS TbDocks, + PRECT rcClient); +HDWP TbdDeferDocks(HDWP hWinPosInfo, + PTOOLBAR_DOCKS TbDocks); +BOOL TbdAddToolbar(PTOOLBAR_DOCKS TbDocks, + const DOCKBAR *Dockbar, + PVOID Context, + const DOCKBAR_ITEM_CALLBACKS *DockbarCallbacks); +BOOL TbdHandleNotifications(PTOOLBAR_DOCKS TbDocks, + LPNMHDR pnmh, + LRESULT *Result); +VOID TbdShowFloatingToolbars(PTOOLBAR_DOCKS TbDocks, + BOOL Show); +BOOL TbdInitImpl(VOID); +VOID TbdUninitImpl(VOID); + +/* mainwnd.c */ +typedef struct _MENU_HINT +{ + WORD CmdId; + UINT HintId; +} MENU_HINT, *PMENU_HINT; + +typedef struct _MAIN_WND_INFO +{ + HWND hSelf; + HWND hMdiClient; + HWND hStatus; + int nCmdShow; + + TOOLBAR_DOCKS ToolDocks; + + /* Editors */ + PEDIT_WND_INFO ImageEditors; + UINT ImagesCreated; + + PVOID ActiveEditor; + + /* status flags */ + BOOL InMenuLoop : 1; +} MAIN_WND_INFO, *PMAIN_WND_INFO; + +BOOL InitMainWindowImpl(VOID); +VOID UninitMainWindowImpl(VOID); +HWND CreateMainWindow(LPCTSTR lpCaption, + int nCmdShow); +BOOL MainWndTranslateMDISysAccel(HWND hwnd, + LPMSG lpMsg); +VOID MainWndSwitchEditorContext(PMAIN_WND_INFO Info, + HWND hDeactivate, + HWND hActivate); +MDI_EDITOR_TYPE MainWndGetCurrentEditor(PMAIN_WND_INFO MainWnd, + PVOID *Info); + +/* misc.c */ +INT AllocAndLoadString(OUT LPTSTR *lpTarget, + IN HINSTANCE hInst, + IN UINT uID); + +DWORD LoadAndFormatString(IN HINSTANCE hInstance, + IN UINT uID, + OUT LPTSTR *lpTarget, + ...); + +BOOL StatusBarLoadAndFormatString(IN HWND hStatusBar, + IN INT PartId, + IN HINSTANCE hInstance, + IN UINT uID, + ...); + +BOOL StatusBarLoadString(IN HWND hStatusBar, + IN INT PartId, + IN HINSTANCE hInstance, + IN UINT uID); + +#endif /* __IMAGESOFT_PRECOMP_H */ diff --git a/reactos/base/applications/imagesoft/resource.h b/reactos/base/applications/imagesoft/resource.h index f879e71c78d..70400defeae 100644 --- a/reactos/base/applications/imagesoft/resource.h +++ b/reactos/base/applications/imagesoft/resource.h @@ -33,8 +33,11 @@ #define ID_REFRESH 3000 #define ID_HELP 3001 -#define ID_WINDOW_TILE 3002 -#define ID_WINDOW_CASCADE 3003 +#define ID_WINDOW_TILE_HORZ 3002 +#define ID_WINDOW_TILE_VERT 3003 +#define ID_WINDOW_CASCADE 3004 +#define ID_WINDOW_NEXT 3005 +#define ID_WINDOW_ARRANGE 3006 /* Menu */ #define IDR_MAINMENU 102 @@ -72,7 +75,22 @@ /* about box info */ #define IDD_ABOUTBOX 200 #define IDC_LICENSE_EDIT 201 -#define IDS_LICENSE 202 -#define IDS_CURPOS 550 -#define IDS_READY 551 +#define IDS_APPNAME 101 +#define IDS_LICENSE 102 +#define IDS_READY 103 +#define IDS_TOOLBAR_STANDARD 201 +#define IDS_TOOLBAR_TEST 202 +#define IDS_IMAGE_NAME 203 + +/* menu hints */ +#define IDS_HINT_EXIT 20001 + +/* system menu hints */ +#define IDS_HINT_SYS_RESTORE 21001 +#define IDS_HINT_SYS_MOVE 21002 +#define IDS_HINT_SYS_SIZE 21003 +#define IDS_HINT_SYS_MINIMIZE 21004 +#define IDS_HINT_SYS_MAXIMIZE 21005 +#define IDS_HINT_SYS_CLOSE 21006 +#define IDS_HINT_SYS_NEXT 21007 diff --git a/reactos/base/applications/imagesoft/tooldock.c b/reactos/base/applications/imagesoft/tooldock.c new file mode 100644 index 00000000000..8db3af5511c --- /dev/null +++ b/reactos/base/applications/imagesoft/tooldock.c @@ -0,0 +1,1032 @@ +#include + +static const TCHAR szToolDockWndClass[] = TEXT("ImageSoftToolDockWndClass"); + +typedef struct _TOOLDOCKWND_INIT +{ + PTOOLBAR_DOCKS TbDocks; + PDOCKBAR_ITEM Item; +} TOOLDOCKWND_INIT, *PTOOLDOCKWND_INIT; + +static UINT +TbdCalculateInsertIndex(PTOOLBAR_DOCKS TbDocks, + DOCK_POSITION Position, + POINT pt) +{ + RECT rcRebar; + UINT Ret = 0; + + GetWindowRect(TbDocks->hRebar[Position], + &rcRebar); + + switch (Position) + { + case TOP_DOCK: + case BOTTOM_DOCK: + if (pt.y > rcRebar.top + ((rcRebar.bottom - rcRebar.top) / 2)) + Ret = (UINT)-1; + break; + + case LEFT_DOCK: + case RIGHT_DOCK: + if (pt.x > rcRebar.left + ((rcRebar.right - rcRebar.left) / 2)) + Ret = (UINT)-1; + break; + + default: + break; + } + + return Ret; +} + +INT +TbdAdjustUpdateClientRect(PTOOLBAR_DOCKS TbDocks, + PRECT rcClient) +{ + INT i, DocksVisible = 0; + + for (i = 0; i < DOCKS_COUNT; i++) + { + if (TbDocks->hRebar[i] != NULL) + { + DocksVisible++; + } + } + + if (DocksVisible != 0) + { + rcClient->top += TbDocks->rcRebar[TOP_DOCK].bottom; + rcClient->left += TbDocks->rcRebar[LEFT_DOCK].right; + rcClient->right -= TbDocks->rcRebar[RIGHT_DOCK].right; + rcClient->bottom -= TbDocks->rcRebar[BOTTOM_DOCK].bottom; + } + + TbDocks->rcClient = *rcClient; + + return DocksVisible; +} + +HDWP +TbdDeferDocks(HDWP hWinPosInfo, + PTOOLBAR_DOCKS TbDocks) +{ + LONG cx, cy; + HDWP hRet = hWinPosInfo; + + cx = TbDocks->rcClient.right - TbDocks->rcClient.left; + cy = TbDocks->rcClient.bottom - TbDocks->rcClient.top; + + /* Top dock */ + if (TbDocks->hRebar[TOP_DOCK] != NULL) + { + hRet = DeferWindowPos(hRet, + TbDocks->hRebar[TOP_DOCK], + NULL, + TbDocks->rcClient.left - TbDocks->rcRebar[LEFT_DOCK].right, + TbDocks->rcClient.top - TbDocks->rcRebar[TOP_DOCK].bottom, + cx + TbDocks->rcRebar[LEFT_DOCK].right + TbDocks->rcRebar[RIGHT_DOCK].right, + TbDocks->rcRebar[TOP_DOCK].bottom, + SWP_NOZORDER); + if (hRet == NULL) + return NULL; + } + + /* Left dock */ + if (TbDocks->hRebar[LEFT_DOCK] != NULL) + { + hRet = DeferWindowPos(hRet, + TbDocks->hRebar[LEFT_DOCK], + NULL, + TbDocks->rcClient.left - TbDocks->rcRebar[LEFT_DOCK].right, + TbDocks->rcClient.top, + TbDocks->rcRebar[LEFT_DOCK].right, + cy, + SWP_NOZORDER); + if (hRet == NULL) + return NULL; + } + + /* Right dock */ + if (TbDocks->hRebar[RIGHT_DOCK] != NULL) + { + hRet = DeferWindowPos(hRet, + TbDocks->hRebar[RIGHT_DOCK], + NULL, + TbDocks->rcClient.right, + TbDocks->rcClient.top, + TbDocks->rcRebar[RIGHT_DOCK].right, + cy, + SWP_NOZORDER); + if (hRet == NULL) + return NULL; + } + + /* Bottom dock */ + if (TbDocks->hRebar[BOTTOM_DOCK] != NULL) + { + hRet = DeferWindowPos(hRet, + TbDocks->hRebar[BOTTOM_DOCK], + NULL, + TbDocks->rcClient.left - TbDocks->rcRebar[LEFT_DOCK].right, + TbDocks->rcClient.bottom, + cx + TbDocks->rcRebar[LEFT_DOCK].right + TbDocks->rcRebar[RIGHT_DOCK].right, + TbDocks->rcRebar[BOTTOM_DOCK].bottom, + SWP_NOZORDER); + if (hRet == NULL) + return NULL; + } + + return hRet; +} + +static PDOCKBAR_ITEM +TbnDockbarItemFromBandId(PTOOLBAR_DOCKS TbDocks, + DOCK_POSITION Position, + UINT uBand) +{ + REBARBANDINFO rbi = {0}; + + rbi.cbSize = sizeof(rbi); + rbi.fMask = RBBIM_LPARAM; + + if (SendMessage(TbDocks->hRebar[Position], + RB_GETBANDINFO, + (WPARAM)uBand, + (LPARAM)&rbi)) + { + return (PDOCKBAR_ITEM)rbi.lParam; + } + + return NULL; +} + +static VOID +TbnRebarChangeSize(PTOOLBAR_DOCKS TbDocks, + DOCK_POSITION Position) +{ + LONG cRebar; + + TbDocks->rcRebar[Position].left = 0; + TbDocks->rcRebar[Position].top = 0; + + cRebar = (LONG)SendMessage(TbDocks->hRebar[Position], + RB_GETBARHEIGHT, + 0, + 0); + + switch (Position) + { + case TOP_DOCK: + case BOTTOM_DOCK: + TbDocks->rcRebar[Position].bottom = cRebar; + break; + + case LEFT_DOCK: + case RIGHT_DOCK: + TbDocks->rcRebar[Position].right = cRebar; + break; + + default: + break; + } + + if (TbDocks->ParentResize != NULL) + { + RECT rcClient = {0}; + + GetClientRect(TbDocks->hParent, + &rcClient); + + TbDocks->ParentResize(TbDocks->Context, + rcClient.right - rcClient.left, + rcClient.bottom - rcClient.top); + } +} + +static VOID +TbnRebarChevronPushed(PTOOLBAR_DOCKS TbDocks, + DOCK_POSITION Position, + LPNMREBARCHEVRON lpnm) +{ + PDOCKBAR_ITEM Item; + + Item = TbnDockbarItemFromBandId(TbDocks, + Position, + lpnm->uBand); + + if (Item != NULL && Item->Callbacks->ChevronPushed) + { + Item->Callbacks->ChevronPushed(TbDocks, + &Item->DockBar, + Item->Context, + Item->hWndClient, + lpnm); + } +} + +static LRESULT +TbnRebarBeginDrag(PTOOLBAR_DOCKS TbDocks, + DOCK_POSITION Position, + LPNMREBAR lpnmrb) +{ + PDOCKBAR_ITEM Item; + + Item = TbnDockbarItemFromBandId(TbDocks, + Position, + lpnmrb->uBand); + + if (Item != NULL) + { + TbDocks->Dragging = Item; + TbDocks->DraggingBandId = lpnmrb->wID; + return FALSE; + } + + return TRUE; +} + +static VOID +TbnRebarEndDrag(PTOOLBAR_DOCKS TbDocks, + DOCK_POSITION Position, + LPNMREBAR lpnmrb) +{ + PDOCKBAR_ITEM Item; + + Item = TbnDockbarItemFromBandId(TbDocks, + Position, + lpnmrb->uBand); + + if (Item != NULL) + { + /* Nothing to do */ + } +} + +BOOL +TbdHandleNotifications(PTOOLBAR_DOCKS TbDocks, + LPNMHDR pnmh, + LRESULT *Result) +{ + BOOL Handled = FALSE; + + if (pnmh->hwndFrom != NULL) + { + DOCK_POSITION Position; + + for (Position = TOP_DOCK; Position < NO_DOCK; Position++) + { + if (pnmh->hwndFrom == TbDocks->hRebar[Position]) + { + switch (pnmh->code) + { + case RBN_HEIGHTCHANGE: + { + TbnRebarChangeSize(TbDocks, + Position); + break; + } + + case RBN_BEGINDRAG: + { + *Result = TbnRebarBeginDrag(TbDocks, + Position, + (LPNMREBAR)pnmh); + break; + } + + case RBN_ENDDRAG: + { + TbnRebarEndDrag(TbDocks, + Position, + (LPNMREBAR)pnmh); + break; + } + + case RBN_CHEVRONPUSHED: + { + TbnRebarChevronPushed(TbDocks, + Position, + (LPNMREBARCHEVRON)pnmh); + break; + } + } + + Handled = TRUE; + break; + } + } + } + + return Handled; +} + +static BOOL +TbdCreateToolbarWnd(PTOOLBAR_DOCKS TbDocks, + PDOCKBAR_ITEM Item, + DOCK_POSITION PrevPosition, + UINT PrevBandIndex, + LPREBARBANDINFO rbi, + POINT pt, + HWND hRebar, + UINT uBand, + BOOL Drag) +{ + LPCTSTR lpCaption = NULL; + TOOLDOCKWND_INIT Init; + HWND hToolbar; + + Init.TbDocks = TbDocks; + Init.Item = Item; + + if (rbi->fMask & RBBIM_TEXT) + { + lpCaption = rbi->lpText; + } + + Item->Callbacks->DockBand(TbDocks, + &Item->DockBar, + Item->Context, + PrevPosition, + NO_DOCK, + rbi); + + if (rbi->fMask & RBBIM_CHILD) + Item->hWndClient = rbi->hwndChild; + else + Item->hWndClient = NULL; + + + if ((rbi->fMask & (RBBIM_CHILDSIZE | RBBIM_SIZE)) == (RBBIM_CHILDSIZE | RBBIM_SIZE)) + { + RECT rcWnd; + static const DWORD dwStyle = WS_POPUPWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_DLGFRAME; + static const DWORD dwExStyle = WS_EX_TOOLWINDOW; + + rcWnd.left = pt.x - GetSystemMetrics(SM_CXFIXEDFRAME) - (GetSystemMetrics(SM_CYSMCAPTION) / 2); + rcWnd.top = pt.y + GetSystemMetrics(SM_CYFIXEDFRAME) + (GetSystemMetrics(SM_CYSMCAPTION) / 2); + rcWnd.right = rcWnd.left + rbi->cx; + rcWnd.bottom = rcWnd.top + rbi->cyMinChild; + + if (AdjustWindowRectEx(&rcWnd, + dwStyle, + FALSE, + dwExStyle)) + { + hToolbar = CreateWindowEx(dwExStyle, + szToolDockWndClass, + lpCaption, + dwStyle, + rcWnd.left, + rcWnd.top, + rcWnd.right - rcWnd.left, + rcWnd.bottom - rcWnd.top, + TbDocks->hParent, + NULL, + hInstance, + &Init); + if (hToolbar != NULL) + { + RECT rcClient; + + if (uBand != (UINT)-1) + { + /* delete the band before showing the client window, + otherwise deleting the band will cause the client + window to be hidden, regardless of whether the band + was hidden before being deleted or not */ + SendMessage(hRebar, + RB_DELETEBAND, + (WPARAM)uBand, + 0); + } + + if (Item->hWndClient != NULL) + { + GetClientRect(hToolbar, + &rcClient); + + SetParent(Item->hWndClient, + hToolbar); + + SetWindowPos(Item->hWndClient, + NULL, + 0, + 0, + rcClient.right, + rcClient.bottom, + SWP_NOZORDER); + + SetWindowPos(Item->hWndClient, + HWND_TOP, + 0, + 0, + 0, + 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + } + + SetWindowPos(hToolbar, + HWND_TOP, + 0, + 0, + 0, + 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + + if (Drag) + { + SetCursor(LoadCursor(NULL, + MAKEINTRESOURCE(IDC_ARROW))); + SendMessage(hToolbar, + WM_NCLBUTTONDOWN, + HTCAPTION, + MAKELPARAM(pt.x, + pt.y)); + } + + return TRUE; + } + } + } + + return FALSE; +} + +static BOOL +TdbInsertToolbar(PTOOLBAR_DOCKS TbDocks, + PDOCKBAR_ITEM Item, + DOCK_POSITION Position) +{ + LPTSTR lpCaption = NULL; + REBARBANDINFO rbi = {0}; + BOOL Ret = FALSE; + + rbi.cbSize = sizeof(rbi); + rbi.fMask = RBBIM_ID | RBBIM_STYLE | RBBIM_LPARAM; + rbi.wID = Item->DockBar.BarId; + rbi.fStyle = RBBS_GRIPPERALWAYS; + rbi.lParam = (LPARAM)Item; + + if (Item->DockBar.DisplayTextId != 0) + { + if (AllocAndLoadString(&lpCaption, + hInstance, + Item->DockBar.DisplayTextId)) + { + rbi.fMask |= RBBIM_TEXT; + rbi.lpText = lpCaption; + } + } + + if (Item->hWndClient != NULL) + { + rbi.fMask |= RBBIM_CHILD; + rbi.hwndChild = Item->hWndClient; + } + + switch (Item->DockBar.Position) + { + case NO_DOCK: + { + POINT pt = {0}; + + /* FIXME - calculate size */ + Ret = TbdCreateToolbarWnd(TbDocks, + Item, + Item->DockBar.Position, + (UINT)-1, + &rbi, + pt, + NULL, + (UINT)-1, + FALSE); + break; + } + + default: + { + UINT Index = -1; + BOOL AddBand = TRUE; + + if (Item->Callbacks->InsertBand != NULL) + { + AddBand = Item->Callbacks->InsertBand(TbDocks, + &Item->DockBar, + Item->Context, + &Index, + &rbi); + } + + if (AddBand) + { + Item->Callbacks->DockBand(TbDocks, + &Item->DockBar, + Item->Context, + NO_DOCK, + Item->DockBar.Position, + &rbi); + + if (rbi.fMask & RBBIM_CHILD) + Item->hWndClient = rbi.hwndChild; + else + Item->hWndClient = NULL; + + Ret = SendMessage(TbDocks->hRebar[Position], + RB_INSERTBAND, + (WPARAM)Index, + (LPARAM)&rbi) != 0; + if (Ret) + { + Item->PrevDock = Position; + Item->PrevBandIndex = (UINT)SendMessage(TbDocks->hRebar[Position], + RB_IDTOINDEX, + (WPARAM)Item->DockBar.BarId, + 0); + } + } + + break; + } + } + + if (lpCaption != NULL) + { + LocalFree((HLOCAL)lpCaption); + } + + return Ret; +} + +BOOL +TbdAddToolbar(PTOOLBAR_DOCKS TbDocks, + const DOCKBAR *Dockbar, + PVOID Context, + const DOCKBAR_ITEM_CALLBACKS *Callbacks) +{ + PDOCKBAR_ITEM Item; + HWND hRebar; + + hRebar = TbDocks->hRebar[Dockbar->Position]; + if (hRebar != NULL) + { + Item = HeapAlloc(ProcessHeap, + 0, + sizeof(DOCKBAR_ITEM)); + if (Item != NULL) + { + /* Initialize the item */ + Item->DockBar = *Dockbar; + Item->Context = Context; + Item->hWndTool = NULL; + Item->PrevDock = Dockbar->Position; + + Item->Callbacks = Callbacks; + + /* Create the client control */ + if (Callbacks->CreateClient != NULL && + !Callbacks->CreateClient(TbDocks, + &Item->DockBar, + Context, + hRebar, + &Item->hWndClient)) + { + HeapFree(ProcessHeap, + 0, + Item); + + return FALSE; + } + + /* Insert the item into the list */ + Item->Next = TbDocks->Items; + TbDocks->Items = Item; + + return TdbInsertToolbar(TbDocks, + Item, + Dockbar->Position); + } + } + + return FALSE; +} + +#define GWLP_DOCKITEM 0 + +static LRESULT CALLBACK +ToolDockWndProc(HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + PTOOLBAR_DOCKS TbDocks; + PDOCKBAR_ITEM Item; + LRESULT Ret = 0; + + /* Get the window context */ + TbDocks = (PTOOLBAR_DOCKS)GetWindowLongPtr(hwnd, + GWLP_USERDATA); + Item = (PDOCKBAR_ITEM)GetWindowLongPtr(hwnd, + GWLP_DOCKITEM); + if ((TbDocks == NULL || Item == NULL) && uMsg != WM_CREATE) + { + goto HandleDefaultMessage; + } + + switch (uMsg) + { + case WM_CREATE: + { + TbDocks = ((PTOOLDOCKWND_INIT)(((LPCREATESTRUCT)lParam)->lpCreateParams))->TbDocks; + Item = ((PTOOLDOCKWND_INIT)(((LPCREATESTRUCT)lParam)->lpCreateParams))->Item; + Item->hWndTool = hwnd; + + SetWindowLongPtr(hwnd, + GWLP_USERDATA, + (LONG_PTR)TbDocks); + SetWindowLongPtr(hwnd, + GWLP_DOCKITEM, + (LONG_PTR)GWLP_DOCKITEM); + break; + } + + case WM_DESTROY: + { + Item->hWndTool = NULL; + + SetWindowLongPtr(hwnd, + GWLP_USERDATA, + 0); + SetWindowLongPtr(hwnd, + GWLP_DOCKITEM, + 0); + break; + } + + default: + { +HandleDefaultMessage: + Ret = DefWindowProc(hwnd, + uMsg, + wParam, + lParam); + break; + } + } + + return Ret; +} + +static LRESULT CALLBACK +RebarSubclassProc(HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam, + UINT_PTR uIdSubclass, + DWORD_PTR dwRefData) +{ + LRESULT Ret; + + Ret = DefSubclassProc(hWnd, + uMsg, + wParam, + lParam); + + if (uMsg == WM_MOUSEMOVE && (wParam & MK_LBUTTON)) + { + DOCK_POSITION Position, DragTo = NO_DOCK; + RECT rcClient; + POINT pt; + PTOOLBAR_DOCKS TbDocks = (PTOOLBAR_DOCKS)dwRefData; + SIZE szTearOff; + + szTearOff.cx = GetSystemMetrics(SM_CXCURSOR); + szTearOff.cy = GetSystemMetrics(SM_CYCURSOR); + + /* + * Check if we're dragging and if it's time to remove the band + */ + if (TbDocks->Dragging != NULL && GetCapture() == hWnd) + { + GetClientRect(hWnd, + &rcClient); + InflateRect(&rcClient, + szTearOff.cx, + szTearOff.cy); + + pt.x = GET_X_LPARAM(lParam); + pt.y = GET_Y_LPARAM(lParam); + + if (!PtInRect(&rcClient, + pt)) + { + REBARBANDINFO rbi; + UINT uBand; + RECT rc; + + /* Save all rebar band information, don't query RBBIM_HEADERSIZE because it + seems to cause problems with toolbars*/ + rbi.cbSize = sizeof(rbi); + rbi.fMask = RBBIM_BACKGROUND | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_COLORS | + RBBIM_IDEALSIZE | RBBIM_ID | RBBIM_IMAGE | RBBIM_LPARAM | RBBIM_SIZE | + RBBIM_STYLE | RBBIM_TEXT; + rbi.lpText = TbDocks->szTempText; + rbi.cch = sizeof(TbDocks->szTempText); + + uBand = (UINT)SendMessage(hWnd, + RB_IDTOINDEX, + (WPARAM)TbDocks->DraggingBandId, + 0); + + if (uBand != (UINT)-1 && + SendMessage(hWnd, + RB_GETBANDINFO, + (WPARAM)uBand, + (LPARAM)&rbi)) + { + MapWindowPoints(hWnd, + HWND_DESKTOP, + &pt, + 1); + + /* Check if the user is trying to drag it into another dock */ + for (Position = TOP_DOCK; Position < NO_DOCK; Position++) + { + if (TbDocks->hRebar[Position] != NULL && + TbDocks->hRebar[Position] != hWnd && + GetWindowRect(TbDocks->hRebar[Position], + &rc)) + { + InflateRect(&rc, + szTearOff.cx, + szTearOff.cy); + + if (PtInRect(&rc, + pt)) + { + DragTo = Position; + break; + } + } + } + + /* Get the current dock */ + for (Position = TOP_DOCK; Position < NO_DOCK; Position++) + { + if (TbDocks->hRebar[Position] == hWnd) + { + break; + } + } + + ReleaseCapture(); + + if (SendMessage(hWnd, + RB_SHOWBAND, + (WPARAM)uBand, + FALSE)) + { + /* Change the parent to the new rebar control */ + if (TbDocks->Dragging->hWndClient != NULL) + { + SetWindowPos(TbDocks->Dragging->hWndClient, + NULL, + 0, + 0, + 0, + 0, + SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER); + + SetParent(TbDocks->Dragging->hWndClient, + TbDocks->hRebar[DragTo]); + + SetWindowPos(TbDocks->Dragging->hWndClient, + NULL, + 0, + 0, + 0, + 0, + SWP_NOSIZE | SWP_NOZORDER); + } + + if (DragTo == NO_DOCK) + { + if (!TbdCreateToolbarWnd(TbDocks, + TbDocks->Dragging, + Position, + uBand, + &rbi, + pt, + hWnd, + uBand, + TRUE)) + { + goto MoveFailed; + } + } + else + { + BOOL Moved = FALSE; + + /* Remove the band from the current rebar control */ + if (SendMessage(hWnd, + RB_DELETEBAND, + (WPARAM)uBand, + 0)) + { + UINT uIndex; + + /* Calculate where to insert the new bar */ + uIndex = TbdCalculateInsertIndex(TbDocks, + DragTo, + pt); + + SetActiveWindow(TbDocks->hRebar[DragTo]); + + TbDocks->Dragging->Callbacks->DockBand(TbDocks, + &TbDocks->Dragging->DockBar, + TbDocks->Dragging->Context, + Position, + DragTo, + &rbi); + + if (rbi.fMask & RBBIM_CHILD) + TbDocks->Dragging->hWndClient = rbi.hwndChild; + else + TbDocks->Dragging->hWndClient = NULL; + + /* Insert the toolbar into the new rebar */ + rbi.fMask |= RBBIM_STYLE; + rbi.fStyle |= RBBS_HIDDEN; + if (SendMessage(TbDocks->hRebar[DragTo], + RB_INSERTBAND, + (WPARAM)uIndex, + (LPARAM)&rbi)) + { + uBand = (UINT)SendMessage(TbDocks->hRebar[DragTo], + RB_IDTOINDEX, + (WPARAM)TbDocks->DraggingBandId, + 0); + + SendMessage(TbDocks->hRebar[DragTo], + RB_SHOWBAND, + (WPARAM)uBand, + TRUE); + + /* Simulate a mouse click to continue dragging */ + if (uBand != (UINT)-1 && + TbDocks->Dragging->hWndClient != NULL && + GetWindowRect(TbDocks->Dragging->hWndClient, + &rc)) + { + switch (DragTo) + { + case LEFT_DOCK: + case RIGHT_DOCK: + pt.x = rc.left + ((rc.right - rc.left) / 2); + pt.y = rc.top - 1; + break; + + default: + pt.x = rc.left - 1; + pt.y = rc.top + ((rc.bottom - rc.top) / 2); + break; + } + + MapWindowPoints(HWND_DESKTOP, + TbDocks->hRebar[DragTo], + &pt, + 1); + + SetCursor(LoadCursor(NULL, + MAKEINTRESOURCE(IDC_SIZEALL))); + + SendMessage(TbDocks->hRebar[DragTo], + WM_LBUTTONDOWN, + wParam, + MAKELPARAM(pt.x, + pt.y)); + + Moved = TRUE; + } + } + } + + if (!Moved) + { +MoveFailed: + TbDocks->Dragging = NULL; + + SendMessage(hWnd, + RB_SHOWBAND, + (WPARAM)uBand, + TRUE); + } + } + } + } + } + } + } + + return Ret; +} + +VOID +TbdShowFloatingToolbars(PTOOLBAR_DOCKS TbDocks, + BOOL Show) +{ + PDOCKBAR_ITEM Item; + + Item = TbDocks->Items; + while (Item != NULL) + { + if (Item->hWndTool != NULL) + { + if ((Show && !IsWindowVisible(Item->hWndTool)) || + (!Show && IsWindowVisible(Item->hWndTool))) + { + ShowWindow(Item->hWndTool, + (Show ? SW_SHOW : SW_HIDE)); + } + } + Item = Item->Next; + } +} + +VOID +TbdInitializeDocks(PTOOLBAR_DOCKS TbDocks, + HWND hWndParent, + PVOID Context, + PDOCKBAR_PARENTRESIZE ParentResizeProc) +{ + DWORD rbStyle = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | + CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_NOMOVEY | CCS_NOMOVEX | + RBS_VARHEIGHT | RBS_AUTOSIZE; + + DOCK_POSITION Position; + + TbDocks->hParent = hWndParent; + TbDocks->Context = Context; + TbDocks->ParentResize = ParentResizeProc; + + for (Position = TOP_DOCK; Position < NO_DOCK; Position++) + { + switch (Position) + { + case LEFT_DOCK: + case RIGHT_DOCK: + rbStyle |= CCS_VERT; + break; + default: + rbStyle &= ~CCS_VERT; + break; + } + + TbDocks->hRebar[Position] = CreateWindowEx(WS_EX_TOOLWINDOW, + REBARCLASSNAME, + NULL, + rbStyle, + 0, + 0, + 0, + 0, + TbDocks->hParent, + NULL, + hInstance, + NULL); + + if (TbDocks->hRebar[Position] != NULL) + { + SetWindowSubclass(TbDocks->hRebar[Position], + RebarSubclassProc, + 1, + (DWORD_PTR)TbDocks); + } + } +} + +BOOL +TbdInitImpl(VOID) +{ + WNDCLASSEX wc = {0}; + + wc.cbSize = sizeof(WNDCLASSEX); + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = ToolDockWndProc; + wc.cbWndExtra = sizeof(PDOCKBAR_ITEM); + wc.hInstance = hInstance; + wc.hCursor = LoadCursor(NULL, + IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); + wc.lpszClassName = szToolDockWndClass; + + return RegisterClassEx(&wc) != (ATOM)0; +} + +VOID +TbdUninitImpl(VOID) +{ + UnregisterClass(szToolDockWndClass, + hInstance); +}