mirror of
git://source.winehq.org/git/wine.git
synced 2024-08-31 13:25:11 +00:00
466 lines
13 KiB
C
466 lines
13 KiB
C
/*
|
|
* Program Manager
|
|
*
|
|
* Copyright 1996 Ulrich Schmid
|
|
* Copyright 2002 Sylvain Petreolle
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library 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
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#define OEMRESOURCE
|
|
|
|
#include "windows.h"
|
|
#include "shellapi.h"
|
|
#include "progman.h"
|
|
|
|
GLOBALS Globals;
|
|
|
|
static VOID MAIN_CreateGroups(void);
|
|
static VOID MAIN_MenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
|
static ATOM MAIN_RegisterMainWinClass(void);
|
|
static VOID MAIN_CreateMainWindow(void);
|
|
static VOID MAIN_CreateMDIWindow(void);
|
|
static VOID MAIN_AutoStart(void);
|
|
|
|
#define BUFFER_SIZE 1000
|
|
|
|
/***********************************************************************
|
|
*
|
|
* WinMain
|
|
*/
|
|
|
|
int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show)
|
|
{
|
|
MSG msg;
|
|
|
|
Globals.lpszIniFile = "progman.ini";
|
|
Globals.lpszIcoFile = "progman.ico";
|
|
|
|
Globals.hInstance = hInstance;
|
|
Globals.hGroups = 0;
|
|
Globals.hActiveGroup = 0;
|
|
|
|
/* Read Options from `progman.ini' */
|
|
Globals.bAutoArrange =
|
|
GetPrivateProfileIntA("Settings", "AutoArrange", 0, Globals.lpszIniFile);
|
|
Globals.bMinOnRun =
|
|
GetPrivateProfileIntA("Settings", "MinOnRun", 0, Globals.lpszIniFile);
|
|
Globals.bSaveSettings =
|
|
GetPrivateProfileIntA("Settings", "SaveSettings", 0, Globals.lpszIniFile);
|
|
|
|
/* Load default icons */
|
|
Globals.hMainIcon = ExtractIconA(Globals.hInstance, Globals.lpszIcoFile, 0);
|
|
Globals.hGroupIcon = ExtractIconA(Globals.hInstance, Globals.lpszIcoFile, 0);
|
|
Globals.hDefaultIcon = ExtractIconA(Globals.hInstance, Globals.lpszIcoFile, 0);
|
|
if (!Globals.hMainIcon) Globals.hMainIcon = LoadIconW(0, (LPWSTR)DEFAULTICON);
|
|
if (!Globals.hGroupIcon) Globals.hGroupIcon = LoadIconW(0, (LPWSTR)DEFAULTICON);
|
|
if (!Globals.hDefaultIcon) Globals.hDefaultIcon = LoadIconW(0, (LPWSTR)DEFAULTICON);
|
|
|
|
/* Register classes */
|
|
if (!prev)
|
|
{
|
|
if (!MAIN_RegisterMainWinClass()) return(FALSE);
|
|
if (!GROUP_RegisterGroupWinClass()) return(FALSE);
|
|
if (!PROGRAM_RegisterProgramWinClass()) return(FALSE);
|
|
}
|
|
|
|
/* Create main window */
|
|
MAIN_CreateMainWindow();
|
|
Globals.hAccel = LoadAcceleratorsW(Globals.hInstance, MAKEINTRESOURCEW(IDA_ACCEL));
|
|
|
|
/* Setup menu, stringtable and resourcenames */
|
|
STRING_LoadMenus();
|
|
|
|
MAIN_CreateMDIWindow();
|
|
|
|
/* Initialize groups */
|
|
MAIN_CreateGroups();
|
|
|
|
/* Start initial applications */
|
|
MAIN_AutoStart();
|
|
|
|
/* Message loop */
|
|
while (GetMessageW (&msg, 0, 0, 0))
|
|
if (!TranslateAcceleratorW(Globals.hMainWnd, Globals.hAccel, &msg))
|
|
{
|
|
TranslateMessage (&msg);
|
|
DispatchMessageW (&msg);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/***********************************************************************
|
|
*
|
|
* MAIN_CreateGroups
|
|
*/
|
|
|
|
static VOID MAIN_CreateGroups(void)
|
|
{
|
|
CHAR buffer[BUFFER_SIZE];
|
|
CHAR szPath[MAX_PATHNAME_LEN];
|
|
CHAR key[20], *ptr;
|
|
|
|
/* Initialize groups according the `Order' entry of `progman.ini' */
|
|
GetPrivateProfileStringA("Settings", "Order", "", buffer, sizeof(buffer), Globals.lpszIniFile);
|
|
ptr = buffer;
|
|
while (ptr < buffer + sizeof(buffer))
|
|
{
|
|
int num, skip, ret;
|
|
ret = sscanf(ptr, "%d%n", &num, &skip);
|
|
if (ret == 0)
|
|
MAIN_MessageBoxIDS_s(IDS_FILE_READ_ERROR_s, Globals.lpszIniFile, IDS_ERROR, MB_OK);
|
|
if (ret != 1) break;
|
|
|
|
sprintf(key, "Group%d", num);
|
|
GetPrivateProfileStringA("Groups", key, "", szPath,
|
|
sizeof(szPath), Globals.lpszIniFile);
|
|
if (!szPath[0]) continue;
|
|
|
|
GRPFILE_ReadGroupFile(szPath);
|
|
|
|
ptr += skip;
|
|
}
|
|
/* FIXME initialize other groups, not enumerated by `Order' */
|
|
}
|
|
|
|
/***********************************************************************
|
|
*
|
|
* MAIN_AutoStart
|
|
*/
|
|
|
|
VOID MAIN_AutoStart(void)
|
|
{
|
|
CHAR buffer[BUFFER_SIZE];
|
|
HLOCAL hGroup, hProgram;
|
|
|
|
GetPrivateProfileStringA("Settings", "AutoStart", "Autostart", buffer,
|
|
sizeof(buffer), Globals.lpszIniFile);
|
|
|
|
for (hGroup = GROUP_FirstGroup(); hGroup; hGroup = GROUP_NextGroup(hGroup))
|
|
if (!lstrcmpA(buffer, GROUP_GroupName(hGroup)))
|
|
for (hProgram = PROGRAM_FirstProgram(hGroup); hProgram;
|
|
hProgram = PROGRAM_NextProgram(hProgram))
|
|
PROGRAM_ExecuteProgram(hProgram);
|
|
}
|
|
|
|
/***********************************************************************
|
|
*
|
|
* MAIN_MainWndProc
|
|
*/
|
|
|
|
static LRESULT CALLBACK MAIN_MainWndProc(HWND hWnd, UINT msg,
|
|
WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (msg)
|
|
{
|
|
case WM_INITMENU:
|
|
CheckMenuItem(Globals.hOptionMenu, PM_AUTO_ARRANGE,
|
|
MF_BYCOMMAND | (Globals.bAutoArrange ? MF_CHECKED : MF_UNCHECKED));
|
|
CheckMenuItem(Globals.hOptionMenu, PM_MIN_ON_RUN,
|
|
MF_BYCOMMAND | (Globals.bMinOnRun ? MF_CHECKED : MF_UNCHECKED));
|
|
CheckMenuItem(Globals.hOptionMenu, PM_SAVE_SETTINGS,
|
|
MF_BYCOMMAND | (Globals.bSaveSettings ? MF_CHECKED : MF_UNCHECKED));
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
if (LOWORD(wParam) < PM_FIRST_CHILD){
|
|
MAIN_MenuCommand(hWnd, LOWORD(wParam), lParam);
|
|
}
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
PostQuitMessage (0);
|
|
break;
|
|
}
|
|
return DefFrameProcW(hWnd, Globals.hMDIWnd, msg, wParam, lParam);
|
|
}
|
|
|
|
/***********************************************************************
|
|
*
|
|
* MAIN_MenuCommand
|
|
*/
|
|
|
|
static VOID MAIN_MenuCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
HLOCAL hActiveGroup = GROUP_ActiveGroup();
|
|
HLOCAL hActiveProgram = PROGRAM_ActiveProgram(hActiveGroup);
|
|
HWND hActiveGroupWnd = GROUP_GroupWnd(hActiveGroup);
|
|
|
|
switch(wParam)
|
|
{
|
|
/* Menu File */
|
|
case PM_NEW:
|
|
switch (DIALOG_New((hActiveGroupWnd && !IsIconic(hActiveGroupWnd)) ?
|
|
PM_NEW_PROGRAM : PM_NEW_GROUP))
|
|
{
|
|
case PM_NEW_PROGRAM:
|
|
if (hActiveGroup) PROGRAM_NewProgram(hActiveGroup);
|
|
break;
|
|
|
|
case PM_NEW_GROUP:
|
|
GROUP_NewGroup();
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case PM_OPEN:
|
|
if (hActiveProgram)
|
|
PROGRAM_ExecuteProgram(hActiveProgram);
|
|
else if (hActiveGroupWnd)
|
|
OpenIcon(hActiveGroupWnd);
|
|
break;
|
|
|
|
case PM_MOVE:
|
|
case PM_COPY:
|
|
if (hActiveProgram)
|
|
PROGRAM_CopyMoveProgram(hActiveProgram, wParam == PM_MOVE);
|
|
break;
|
|
|
|
case PM_DELETE:
|
|
if (hActiveProgram)
|
|
{
|
|
if (DIALOG_Delete(IDS_DELETE_PROGRAM_s, PROGRAM_ProgramName(hActiveProgram)))
|
|
PROGRAM_DeleteProgram(hActiveProgram, TRUE);
|
|
}
|
|
else if (hActiveGroup)
|
|
{
|
|
if (DIALOG_Delete(IDS_DELETE_GROUP_s, GROUP_GroupName(hActiveGroup)))
|
|
GROUP_DeleteGroup(hActiveGroup);
|
|
}
|
|
break;
|
|
|
|
case PM_ATTRIBUTES:
|
|
if (hActiveProgram)
|
|
PROGRAM_ModifyProgram(hActiveProgram);
|
|
else if (hActiveGroup)
|
|
GROUP_ModifyGroup(hActiveGroup);
|
|
break;
|
|
|
|
case PM_EXECUTE:
|
|
DIALOG_Execute();
|
|
break;
|
|
|
|
case PM_EXIT:
|
|
PostQuitMessage(0);
|
|
break;
|
|
|
|
/* Menu Options */
|
|
case PM_AUTO_ARRANGE:
|
|
Globals.bAutoArrange = !Globals.bAutoArrange;
|
|
CheckMenuItem(Globals.hOptionMenu, PM_AUTO_ARRANGE,
|
|
MF_BYCOMMAND | (Globals.bAutoArrange ?
|
|
MF_CHECKED : MF_UNCHECKED));
|
|
WritePrivateProfileStringA("Settings", "AutoArrange",
|
|
Globals.bAutoArrange ? "1" : "0",
|
|
Globals.lpszIniFile);
|
|
WritePrivateProfileStringA(NULL,NULL,NULL,Globals.lpszIniFile); /* flush it */
|
|
break;
|
|
|
|
case PM_MIN_ON_RUN:
|
|
Globals.bMinOnRun = !Globals.bMinOnRun;
|
|
CheckMenuItem(Globals.hOptionMenu, PM_MIN_ON_RUN,
|
|
MF_BYCOMMAND | (Globals.bMinOnRun ?
|
|
MF_CHECKED : MF_UNCHECKED));
|
|
WritePrivateProfileStringA("Settings", "MinOnRun",
|
|
Globals.bMinOnRun ? "1" : "0",
|
|
Globals.lpszIniFile);
|
|
WritePrivateProfileStringA(NULL,NULL,NULL,Globals.lpszIniFile); /* flush it */
|
|
break;
|
|
|
|
case PM_SAVE_SETTINGS:
|
|
Globals.bSaveSettings = !Globals.bSaveSettings;
|
|
CheckMenuItem(Globals.hOptionMenu, PM_SAVE_SETTINGS,
|
|
MF_BYCOMMAND | (Globals.bSaveSettings ?
|
|
MF_CHECKED : MF_UNCHECKED));
|
|
WritePrivateProfileStringA("Settings", "SaveSettings",
|
|
Globals.bSaveSettings ? "1" : "0",
|
|
Globals.lpszIniFile);
|
|
WritePrivateProfileStringA(NULL,NULL,NULL,Globals.lpszIniFile); /* flush it */
|
|
break;
|
|
|
|
/* Menu Windows */
|
|
case PM_OVERLAP:
|
|
SendMessageW(Globals.hMDIWnd, WM_MDICASCADE, 0, 0);
|
|
break;
|
|
|
|
case PM_SIDE_BY_SIDE:
|
|
SendMessageW(Globals.hMDIWnd, WM_MDITILE, MDITILE_VERTICAL, 0);
|
|
break;
|
|
|
|
case PM_ARRANGE:
|
|
|
|
if (hActiveGroupWnd && !IsIconic(hActiveGroupWnd))
|
|
ArrangeIconicWindows(hActiveGroupWnd);
|
|
else
|
|
SendMessageW(Globals.hMDIWnd, WM_MDIICONARRANGE, 0, 0);
|
|
break;
|
|
|
|
/* Menu Help */
|
|
case PM_CONTENTS:
|
|
if (!WinHelpA(Globals.hMainWnd, "progman.hlp", HELP_CONTENTS, 0))
|
|
MAIN_MessageBoxIDS(IDS_WINHELP_ERROR, IDS_ERROR, MB_OK);
|
|
break;
|
|
|
|
case PM_ABOUT_WINE:
|
|
ShellAboutA(hWnd, "WINE", "Program Manager", 0);
|
|
break;
|
|
|
|
default:
|
|
MAIN_MessageBoxIDS(IDS_NOT_IMPLEMENTED, IDS_ERROR, MB_OK);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
*
|
|
* MAIN_RegisterMainWinClass
|
|
*/
|
|
|
|
static ATOM MAIN_RegisterMainWinClass(void)
|
|
{
|
|
WNDCLASSW class;
|
|
|
|
class.style = CS_HREDRAW | CS_VREDRAW;
|
|
class.lpfnWndProc = MAIN_MainWndProc;
|
|
class.cbClsExtra = 0;
|
|
class.cbWndExtra = 0;
|
|
class.hInstance = Globals.hInstance;
|
|
class.hIcon = Globals.hMainIcon;
|
|
class.hCursor = LoadCursorW (0, (LPWSTR)IDC_ARROW);
|
|
class.hbrBackground = GetStockObject (NULL_BRUSH);
|
|
class.lpszMenuName = 0;
|
|
class.lpszClassName = STRING_MAIN_WIN_CLASS_NAME;
|
|
|
|
return RegisterClassW(&class);
|
|
}
|
|
|
|
/***********************************************************************
|
|
*
|
|
* MAIN_CreateMainWindow
|
|
*/
|
|
|
|
static VOID MAIN_CreateMainWindow(void)
|
|
{
|
|
INT left , top, right, bottom, width, height, show;
|
|
CHAR buffer[100];
|
|
|
|
Globals.hMDIWnd = 0;
|
|
Globals.hMainMenu = 0;
|
|
|
|
/* Get the geometry of the main window */
|
|
GetPrivateProfileStringA("Settings", "Window", "", buffer, sizeof(buffer), Globals.lpszIniFile);
|
|
if (5 == sscanf(buffer, "%d %d %d %d %d", &left, &top, &right, &bottom, &show))
|
|
{
|
|
width = right - left;
|
|
height = bottom - top;
|
|
}
|
|
else
|
|
{
|
|
left = top = width = height = CW_USEDEFAULT;
|
|
show = SW_SHOWNORMAL;
|
|
}
|
|
|
|
/* Create main Window */
|
|
Globals.hMainWnd =
|
|
CreateWindowW(STRING_MAIN_WIN_CLASS_NAME, NULL,
|
|
WS_OVERLAPPEDWINDOW, left, top, width, height,
|
|
0, 0, Globals.hInstance, 0);
|
|
|
|
ShowWindow (Globals.hMainWnd, show);
|
|
UpdateWindow (Globals.hMainWnd);
|
|
}
|
|
|
|
/***********************************************************************
|
|
*
|
|
* MAIN_CreateMDIWindow
|
|
*/
|
|
|
|
static VOID MAIN_CreateMDIWindow(void)
|
|
{
|
|
CLIENTCREATESTRUCT ccs;
|
|
RECT rect;
|
|
|
|
/* Get the geometry of the MDI window */
|
|
GetClientRect(Globals.hMainWnd, &rect);
|
|
|
|
ccs.hWindowMenu = Globals.hWindowsMenu;
|
|
ccs.idFirstChild = PM_FIRST_CHILD;
|
|
|
|
/* Create MDI Window */
|
|
Globals.hMDIWnd =
|
|
CreateWindowW(STRING_MDI_WIN_CLASS_NAME, NULL,
|
|
WS_CHILD, rect.left, rect.top,
|
|
rect.right - rect.left, rect.bottom - rect.top,
|
|
Globals.hMainWnd, 0,
|
|
Globals.hInstance, &ccs);
|
|
|
|
ShowWindow (Globals.hMDIWnd, SW_SHOW);
|
|
UpdateWindow (Globals.hMDIWnd);
|
|
}
|
|
|
|
/**********************************************************************/
|
|
/***********************************************************************
|
|
*
|
|
* MAIN_MessageBoxIDS
|
|
*/
|
|
INT MAIN_MessageBoxIDS(UINT ids_text, UINT ids_title, WORD type)
|
|
{
|
|
CHAR text[MAX_STRING_LEN];
|
|
CHAR title[MAX_STRING_LEN];
|
|
|
|
LoadStringA(Globals.hInstance, ids_text, text, sizeof(text));
|
|
LoadStringA(Globals.hInstance, ids_title, title, sizeof(title));
|
|
|
|
return(MessageBoxA(Globals.hMainWnd, text, title, type));
|
|
}
|
|
|
|
/***********************************************************************
|
|
*
|
|
* MAIN_MessageBoxIDS_s
|
|
*/
|
|
INT MAIN_MessageBoxIDS_s(UINT ids_text, LPCSTR str, UINT ids_title, WORD type)
|
|
{
|
|
CHAR text[MAX_STRING_LEN];
|
|
CHAR title[MAX_STRING_LEN];
|
|
CHAR newtext[MAX_STRING_LEN + MAX_PATHNAME_LEN];
|
|
|
|
LoadStringA(Globals.hInstance, ids_text, text, sizeof(text));
|
|
LoadStringA(Globals.hInstance, ids_title, title, sizeof(title));
|
|
wsprintfA(newtext, text, str);
|
|
|
|
return(MessageBoxA(Globals.hMainWnd, newtext, title, type));
|
|
}
|
|
|
|
/***********************************************************************
|
|
*
|
|
* MAIN_ReplaceString
|
|
*/
|
|
|
|
VOID MAIN_ReplaceString(HLOCAL *handle, LPSTR replace)
|
|
{
|
|
HLOCAL newhandle = LocalAlloc(LMEM_FIXED, strlen(replace) + 1);
|
|
if (newhandle)
|
|
{
|
|
LPSTR newstring = LocalLock(newhandle);
|
|
strcpy(newstring, replace);
|
|
LocalFree(*handle);
|
|
*handle = newhandle;
|
|
}
|
|
else MAIN_MessageBoxIDS(IDS_OUT_OF_MEMORY, IDS_ERROR, MB_OK);
|
|
}
|