Release 960302
Sat Mar 2 18:19:06 1996 Alexandre Julliard <julliard@lrc.epfl.ch>
* [controls/scroll.c]
Fixed SCROLL_THUMB painting fixes from Alex Korobka to store the
current tracking window.
* [files/file.c]
Fixed two file descriptor leaks in FILE_OpenFile().
* [if1632/relay32.c] [loader/module.c] [loader/pe_image.c]
[tools/build.c]
Replaced LOADEDFILEINFO structure by OFSTRUCT.
* [memory/atom.c]
Reload the pointer to the atom table in ATOM_GetTable() and
ATOM_AddAtom() in case the LOCAL_Alloc() calls caused the table to
move in linear memory.
Fri Mar 1 11:57:13 1996 Frans van Dorsselaer <dorssel@rulhm1.leidenuniv.nl>
* [include/callback.h]
Added support for CallWordBreakProc().
* [controls/edit.c]
New caret handling (really efficient / fast).
Implemented EM_SETWORDBREAKPROC and EM_GETWORDBREAKPROC.
Fixed EM_SETFONT so it now also creates a proper new caret.
Wed Feb 28 22:03:34 1996 Daniel Schepler <daniel@frobnitz.wustl.edu>
* [controls/desktop.c] [misc/main.c] [windows/event.c] [windows/win.c]
Added WM_DELETE protocol to top-level windows.
* [controls/scroll.c]
Fixed a problem which caused slow scrolling to continue uncontrollably.
* [misc/exec.c]
Implemented ExitWindows().
* [windows/win.c]
Set top-level owned windows to be transient.
Wed Feb 28 19:13:22 1996 Ulrich Schmid <uschmid@mail.hh.provi.de>
* [programs/progman/*]
Added a program manager.
Wed Feb 28 18:38:01 1996 Duncan C Thomson <duncan@spd.eee.strath.ac.uk>
* [resources/sysres_Eo.c]
Added support for Esperanto [Eo] language.
Wed Feb 28 00:23:00 1996 Thomas Sandford <t.d.g.sandford@prds-grn.demon.co.uk>
* [if1632/user32.spec]
Added EndDialog, GetDlgItem, GetDlgItemInt, SetDlgItemInt,
* [win32/init.c]
Added task.h to includes. GetModuleHandleA() - return hInstance
if called with NULL parameter. Freecell needs this. NOTE this
may indicate a problem with differentiation between hModule and
hInstance within Wine.
* [win32/resource.c]
FindResource32() and LoadResource32() - Removed #if 0's around
conversion from hInstance to hModule. See remarks above.
* [win32/string32.c]
WIN32_UniLen() - removed stray semicolon.
Tue Feb 27 21:05:18 1996 Jim Peterson <jspeter@birch.ee.vt.edu>
* [windows/caret.c]
Set blink rate with call to GetProfileInt().
* [rc/winerc.c]
In new_style(), made initial flag settings WS_CHILD | WS_VISIBLE
instead of 0. This seems to correspond to Borland's defaults, and
the flags can be unset by using the (rather obtuse) "| NOT WS_CHILD"
or "| NOT WS_VISIBLE" technique in the *.rc file.
* [win32/time.c]
In GetLocalTime() and GetSystemTime(), used tv_sec field of result
returned by gettimeofday() instead of making second call to
time(). This eliminates clock jitter if the seconds change
between the two calls (rare, but possible).
* [include/wintypes.h]
Added "#define _far" and "#define _pascal".
* [windows/win.c]
Added function GetDesktopHwnd().
* [include/xmalloc.h]
Removed the '#ifdef HAVE_STDLIB_H' structure, since it seemed to
have been removed from 'configure', and was causing redefinition
warnings.
Tue Feb 27 19:31:11 1996 Albrecht Kleine <kleine@ak.sax.de>
* [windows/winpos.c]
Added RDW_ALLCHILDREN flag in SetWindowPos (handling SWP_FRAMECHANGED)
to force a repaint when setting menu bars with different rows.
Sun Feb 25 21:15:00 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu>
* [windows/syscolors.c] [controls/scroll.c]
Fixed DrawFocusRect pen and SCROLL_THUMB painting.
diff --git a/programs/progman/ChangeLog b/programs/progman/ChangeLog
new file mode 100644
index 0000000..7a14e2d
--- /dev/null
+++ b/programs/progman/ChangeLog
@@ -0,0 +1,6 @@
+Wed Feb 28 19:21:55 1996 Ulrich Schmid <uschmid@mail.hh.provi.de>
+
+ * [progman.h] [main.c] [group.c] [program.c] [dialog.c]
+ [grpfile.c] [string.c] [winexec.c] [license.h] [license.c] [Xx.rc]
+ [accel.rc] [En.rc] [Strings_En.c] [License_En.c] [De.rc]
+ [Strings_De.c] Original by Ulrich Schmid
diff --git a/programs/progman/De.rc b/programs/progman/De.rc
new file mode 100644
index 0000000..9284517
--- /dev/null
+++ b/programs/progman/De.rc
@@ -0,0 +1,93 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid
+ */
+
+/* Menu */
+
+#define MENU_Xx MENU_De
+
+#define MENU_FILE "&Datei"
+#define MENU_FILE_NEW "&Neu..."
+#define MENU_FILE_OPEN "Ö&ffnen\tEingabetaste"
+#define MENU_FILE_MOVE "&Verschieben...\tF7"
+#define MENU_FILE_COPY "&Kopieren...\tF8"
+#define MENU_FILE_DELETE "&Löschen\tEntf"
+#define MENU_FILE_ATTRIBUTES "&Eigenschaften...\tAlt+Eingabetaste"
+#define MENU_FILE_EXECUTE "&Ausführen..."
+#define MENU_FILE_EXIT "&Programm-Manager &beenden..."
+
+#define MENU_OPTIONS "&Optionen"
+#define MENU_OPTIONS_AUTO_ARRANGE "&Automatisch anordnen"
+#define MENU_OPTIONS_MIN_ON_RUN "&Symbol nach Programmstart"
+#define MENU_OPTIONS_SAVE_SETTINGS "&Einstellungen beim Beenden speichern"
+
+#define MENU_WINDOWS "&Fenster"
+#define MENU_WINDOWS_OVERLAP "Über&lappend\tUmschalt+F5"
+#define MENU_WINDOWS_SIDE_BY_SIDE "&Nebeneinander\tUmschalt+F4"
+#define MENU_WINDOWS_ARRANGE "&Symbole anordnen"
+
+#define MENU_LANGUAGE "&Sprache"
+
+#define MENU_HELP "&Hilfe"
+#define MENU_HELP_CONTENTS "&Inhalt"
+#define MENU_HELP_SEARCH "&Suchen..."
+#define MENU_HELP_HELP_ON_HELP "&Hilfe benutzen"
+#define MENU_HELP_TUTORIAL "&Lernprogramm"
+
+#define MENU_INFO "Inf&o..."
+#define MENU_INFO_LICENSE "&Lizenz"
+#define MENU_INFO_NO_WARRANTY "&KEINE GARANTIE"
+#define MENU_INFO_ABOUT_WINE "&Über WINE"
+
+/* Dialogs */
+
+#define DIALOG_OK "OK"
+#define DIALOG_CANCEL "Abbrechen"
+#define DIALOG_BROWSE "&Durchsuchen..."
+#define DIALOG_HELP "&Hilfe"
+
+#define DIALOG_NEW_Xx DIALOG_NEW_De
+#define DIALOG_NEW_CAPTION "Neues Programmobject"
+#define DIALOG_NEW_NEW "Neu"
+#define DIALOG_NEW_GROUP "Programmgrupp&e"
+#define DIALOG_NEW_PROGRAM "&Programm"
+
+#define DIALOG_MOVE_Xx DIALOG_MOVE_De
+#define DIALOG_MOVE_CAPTION "Programm verschieben"
+#define DIALOG_MOVE_PROGRAM "Verschiebe Programm:"
+#define DIALOG_MOVE_FROM_GROUP "Von Programmgruppe:"
+#define DIALOG_MOVE_TO_GROUP "&In Gruppe:"
+
+#define DIALOG_COPY_Xx DIALOG_COPY_De
+#define DIALOG_COPY_CAPTION "Programm kopieren"
+#define DIALOG_COPY_PROGRAM "Kopiere Programm:"
+#define DIALOG_COPY_FROM_GROUP DIALOG_MOVE_FROM_GROUP
+#define DIALOG_COPY_TO_GROUP DIALOG_MOVE_TO_GROUP
+
+#define DIALOG_GROUP_Xx DIALOG_GROUP_De
+#define DIALOG_GROUP_CAPTION "Programmgruppeneigenschaften"
+#define DIALOG_GROUP_DESCRIPTION "&Beschreibung:"
+#define DIALOG_GROUP_FILE "&Gruppendatei:"
+
+#define DIALOG_PROGRAM_Xx DIALOG_PROGRAM_De
+#define DIALOG_PROGRAM_CAPTION "Programmeigenschaften"
+#define DIALOG_PROGRAM_DESCRIPTION DIALOG_GROUP_DESCRIPTION
+#define DIALOG_PROGRAM_COMMAND_LINE "Befehls&zeile:"
+#define DIALOG_PROGRAM_DIRECTORY "&Arbeitsverzeichnis:"
+#define DIALOG_PROGRAM_HOT_KEY "&Tastenkombination:"
+#define DIALOG_PROGRAM_SYMBOL "Als Sy&mbol"
+#define DIALOG_PROGRAM_OTHER_SYMBOL "Anderes &Symbol..."
+
+#define DIALOG_SYMBOL_Xx DIALOG_SYMBOL_De
+#define DIALOG_SYMBOL_CAPTION "Symbol auswählen"
+#define DIALOG_SYMBOL_FILE "Datei&name:"
+#define DIALOG_SYMBOL_CURRENT "&Aktuelles Symbol:"
+
+#define DIALOG_EXECUTE_Xx DIALOG_EXECUTE_De
+#define DIALOG_EXECUTE_CAPTION "Programm Ausführen"
+#define DIALOG_EXECUTE_COMMAND_LINE DIALOG_PROGRAM_COMMAND_LINE
+#define DIALOG_EXECUTE_SYMBOL DIALOG_PROGRAM_SYMBOL
+
+#include "Xx.rc"
diff --git a/programs/progman/En.rc b/programs/progman/En.rc
new file mode 100644
index 0000000..97fb14b
--- /dev/null
+++ b/programs/progman/En.rc
@@ -0,0 +1,93 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid
+ */
+
+/* Menu */
+
+#define MENU_Xx MENU_En
+
+#define MENU_FILE "&File"
+#define MENU_FILE_NEW "&New..."
+#define MENU_FILE_OPEN "O&pen\tEnter"
+#define MENU_FILE_MOVE "&Move...\tF7"
+#define MENU_FILE_COPY "&Copy...\tF8"
+#define MENU_FILE_DELETE "&Delete\tEntf"
+#define MENU_FILE_ATTRIBUTES "&Attributes...\tAlt+Enter"
+#define MENU_FILE_EXECUTE "&Execute..."
+#define MENU_FILE_EXIT "E&xit Windows..."
+
+#define MENU_OPTIONS "&Options"
+#define MENU_OPTIONS_AUTO_ARRANGE "&Arrange automatically"
+#define MENU_OPTIONS_MIN_ON_RUN "&Minimize on run"
+#define MENU_OPTIONS_SAVE_SETTINGS "&Save settings on exit"
+
+#define MENU_WINDOWS "&Windows"
+#define MENU_WINDOWS_OVERLAP "&Overlapped\tShift+F5"
+#define MENU_WINDOWS_SIDE_BY_SIDE "&Side by side\tShift+F4"
+#define MENU_WINDOWS_ARRANGE "&Arrange Symbols"
+
+#define MENU_LANGUAGE "&Language"
+
+#define MENU_HELP "&Help"
+#define MENU_HELP_CONTENTS "&Contents"
+#define MENU_HELP_SEARCH "&Search..."
+#define MENU_HELP_HELP_ON_HELP "&Help on Help"
+#define MENU_HELP_TUTORIAL "&Tutorial"
+
+#define MENU_INFO "&Info..."
+#define MENU_INFO_LICENSE "&License"
+#define MENU_INFO_NO_WARRANTY "&NO WARRANTY"
+#define MENU_INFO_ABOUT_WINE "&About WINE"
+
+/* Dialogs */
+
+#define DIALOG_OK "OK"
+#define DIALOG_CANCEL "Cancel"
+#define DIALOG_BROWSE "&Browse"
+#define DIALOG_HELP "&Help"
+
+#define DIALOG_NEW_Xx DIALOG_NEW_En
+#define DIALOG_NEW_CAPTION "New Program Object"
+#define DIALOG_NEW_NEW "New"
+#define DIALOG_NEW_GROUP "Program &group"
+#define DIALOG_NEW_PROGRAM "&Program"
+
+#define DIALOG_MOVE_Xx DIALOG_MOVE_En
+#define DIALOG_MOVE_CAPTION "Move Program"
+#define DIALOG_MOVE_PROGRAM "Move program:"
+#define DIALOG_MOVE_FROM_GROUP "From group:"
+#define DIALOG_MOVE_TO_GROUP "&To group:"
+
+#define DIALOG_COPY_Xx DIALOG_COPY_En
+#define DIALOG_COPY_CAPTION "Copy Program"
+#define DIALOG_COPY_PROGRAM "Copy program:"
+#define DIALOG_COPY_FROM_GROUP DIALOG_MOVE_FROM_GROUP
+#define DIALOG_COPY_TO_GROUP DIALOG_MOVE_TO_GROUP
+
+#define DIALOG_GROUP_Xx DIALOG_GROUP_En
+#define DIALOG_GROUP_CAPTION "Program Group Attributes"
+#define DIALOG_GROUP_DESCRIPTION "&Description:"
+#define DIALOG_GROUP_FILE "&Group file:"
+
+#define DIALOG_PROGRAM_Xx DIALOG_PROGRAM_En
+#define DIALOG_PROGRAM_CAPTION "Program Attributes"
+#define DIALOG_PROGRAM_DESCRIPTION DIALOG_GROUP_DESCRIPTION
+#define DIALOG_PROGRAM_COMMAND_LINE "&Command line:"
+#define DIALOG_PROGRAM_DIRECTORY "&Working directory:"
+#define DIALOG_PROGRAM_HOT_KEY "&Key combination:"
+#define DIALOG_PROGRAM_SYMBOL "As &Symbol"
+#define DIALOG_PROGRAM_OTHER_SYMBOL "&Other Symbol..."
+
+#define DIALOG_SYMBOL_Xx DIALOG_SYMBOL_En
+#define DIALOG_SYMBOL_CAPTION "Select Symbol"
+#define DIALOG_SYMBOL_FILE "&Filename:"
+#define DIALOG_SYMBOL_CURRENT "&Current Symbol:"
+
+#define DIALOG_EXECUTE_Xx DIALOG_EXECUTE_En
+#define DIALOG_EXECUTE_CAPTION "Execute Program"
+#define DIALOG_EXECUTE_COMMAND_LINE DIALOG_PROGRAM_COMMAND_LINE
+#define DIALOG_EXECUTE_SYMBOL DIALOG_PROGRAM_SYMBOL
+
+#include "Xx.rc"
diff --git a/programs/progman/License_En.c b/programs/progman/License_En.c
new file mode 100644
index 0000000..efe3437
--- /dev/null
+++ b/programs/progman/License_En.c
@@ -0,0 +1,47 @@
+#include <windows.h>
+#include "license.h"
+
+static CHAR LicenseCaption_En[] = "LICENSE";
+static CHAR License_En[] = "\
+You may without charge, royalty or other payment, copy and\
+ distribute copies of this work and derivative works of this work\
+ in source or binary form provided that: (1)\
+ you appropriately publish on each copy an appropriate copyright\
+ notice; (2) faithfully reproduce all prior copyright notices\
+ included in the original work (you may also add your own\
+ copyright notice); and (3) agree to indemnify and hold all prior\
+ authors, copyright holders and licensors of the work harmless\
+ from and against all damages arising from use of the work.\
+\n\
+You may distribute sources of derivative works of the work\
+ provided that (1) (a) all source files of the original work that\
+ have been modified, (b) all source files of the derivative work\
+ that contain any party of the original work, and (c) all source\
+ files of the derivative work that are necessary to compile, link\
+ and run the derivative work without unresolved external calls and\
+ with the same functionality of the original work (\"Necessary\
+ Sources\") carry a prominent notice explaining the nature and date\
+ of the modification and/or creation. You are encouraged to make\
+ the Necessary Sources available under this license in order to\
+ further the development and acceptance of the work.\
+\n\
+EXCEPT AS OTHERWISE RESTRICTED BY LAW, THIS WORK IS PROVIDED\
+ WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND, INCLUDING\
+ BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF FITNESS FOR A\
+ PARTICULAR PURPOSE, MERCHANTABILITY OR TITLE. EXCEPT AS\
+ OTHERWISE PROVIDED BY LAW, NO AUTHOR, COPYRIGHT HOLDER OR\
+ LICENSOR SHALL BE LIABLE TO YOU FOR DAMAGES OF ANY KIND, EVEN IF\
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.";
+
+static CHAR NoWarrantyCaption_En[] = "NO WARRANTY";
+static CHAR NoWarranty_En[] = "\
+EXCEPT AS OTHERWISE RESTRICTED BY LAW, THIS WORK IS PROVIDED\
+ WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES OF ANY KIND, INCLUDING\
+ BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF FITNESS FOR A\
+ PARTICULAR PURPOSE, MERCHANTABILITY OR TITLE. EXCEPT AS\
+ OTHERWISE PROVIDED BY LAW, NO AUTHOR, COPYRIGHT HOLDER OR\
+ LICENSOR SHALL BE LIABLE TO YOU FOR DAMAGES OF ANY KIND, EVEN IF\
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.";
+
+LICENSE WineLicense_En = {License_En, LicenseCaption_En,
+ NoWarranty_En, NoWarrantyCaption_En};
diff --git a/programs/progman/Makefile.in b/programs/progman/Makefile.in
new file mode 100644
index 0000000..32f4a44
--- /dev/null
+++ b/programs/progman/Makefile.in
@@ -0,0 +1,41 @@
+TOPSRC = @top_srcdir@
+MODULE = none
+PROGRAMS = progman
+ALL_LIBS = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LDLIBS)
+
+LANGUAGES = En De
+LICENSELANG = En
+
+MOSTOBJS = \
+ dialog.o \
+ group.o \
+ grpfile.o \
+ license.o \
+ main.o \
+ program.o \
+ winexec.o
+
+STRINGOBJS = \
+ accel.o \
+ string.o \
+ $(LANGUAGES:%=%.o) \
+ $(LICENSELANG:%=License_%.o) \
+ $(LANGUAGES:%=Strings_%.o)
+
+C_SRCS = $(MOSTOBJS:.o=.c) $(STRINGOBJS:.o=.c)
+
+all: check_winerc $(PROGRAMS)
+
+@MAKE_RULES@
+
+# Some strings need addresses >= 0x10000
+progman: $(MOSTOBJS) $(STRINGOBJS)
+ $(CC) -o progman $(MOSTOBJS) $(LDOPTIONS) $(ALL_LIBS) $(STRINGOBJS)
+
+clean::
+ $(RM) accel.c accel.h $(LANGUAGES:%=%.c) $(LANGUAGES:%=%.h) progman
+
+accel.c accel.h: $(WINERC) Xx.rc
+$(LANGUAGES:%=%.c) $(LANGUAGES:%=%.h): $(WINERC) Xx.rc
+
+### Dependencies:
diff --git a/programs/progman/README b/programs/progman/README
new file mode 100644
index 0000000..b145c28
--- /dev/null
+++ b/programs/progman/README
@@ -0,0 +1,16 @@
+This is a Program Manager for WINE.
+
+There is a checksum in the Microsoft `*.grp' files. I don't know how
+to calculate it. Therefore the group files written by this Program Manager
+cannot be used with the Microsoft Program Manager!!
+
+To prevent overwriting original files:
+If there is an existing `*.grp' file this program uses the extension
+`.gr' instead.
+
+It's possible to use an alternate `progman.ini' file by adding to
+`wine.conf' something like:
+[progman]
+progman.ini=/my/wine/path/progman.ini
+
+It's possible to start both Windows and UNIX programs.
diff --git a/programs/progman/Strings_De.c b/programs/progman/Strings_De.c
new file mode 100644
index 0000000..de3d369
--- /dev/null
+++ b/programs/progman/Strings_De.c
@@ -0,0 +1,34 @@
+#include <windows.h>
+#include "progman.h"
+
+LPCSTR StringTableDe[NUMBER_OF_STRINGS] =
+{
+ "Programm-Manager",
+ "FEHLER",
+ "Information",
+ "Löschen",
+ "Lösche Programmgruppe `%s' ?",
+ "Lösche Programm `%s' ?",
+ "Nicht implementiert",
+ "Fehler beim Lesen von `%s'",
+ "Fehler beim Schreiben von `%s'",
+
+ "Die Programmgruppendatei `%s' kann nicht geöffnet werden.\n"
+ "Soll weiterhin versucht werden, diese Datei zu laden?",
+
+ "Zu wenig Hauptspeicher",
+ "Keine Hilfe verfügbar",
+ "Unbekannte Eigenschaft der `.grp' Datei",
+ "Datei `%s' existiert. Sie wird nicht überschrieben.",
+ "Die Programmgruppe wird als `%s' gesichert um das Überschreiben der Originaldatei zu verhindern.",
+ "Keine",
+
+ "Alle Dateien (*.*)\0" "*.*\0"
+ "Programme\0" "*.exe;*.pif;*.com;*.bat\0",
+
+ "Alle Dateien (*.*)\0" "*.*\0"
+ "Bibliotheken (*.dll)\0" "*.dll\0"
+ "Programme\0" "*.exe\0"
+ "Symboldateien\0" "*.ico;*.exe;*.dll\0"
+ "Symbole (*.ico)\0" "*.ico\0"
+};
diff --git a/programs/progman/Strings_En.c b/programs/progman/Strings_En.c
new file mode 100644
index 0000000..da3f19d
--- /dev/null
+++ b/programs/progman/Strings_En.c
@@ -0,0 +1,34 @@
+#include <windows.h>
+#include "progman.h"
+
+LPCSTR StringTableEn[NUMBER_OF_STRINGS] =
+{
+ "Program Manager",
+ "ERROR",
+ "Information",
+ "Delete",
+ "Delete group `%s' ?",
+ "Delete program `%s' ?",
+ "Not implemented",
+ "Error reading `%s'",
+ "Error writeing `%s'",
+
+ "The group file `%s' cannot be opened.\n"
+ "Should it be tried further on?",
+
+ "Out of memory",
+ "Help not available",
+ "Unknown feature in `.grp' file",
+ "File `%s' exists. Not overwritten.",
+ "Save group as `%s' to prevent overwriting original files",
+ "None",
+
+ "All files (*.*)\0" "*.*\0"
+ "Programs\0" "*.exe;*.pif;*.com;*.bat\0",
+
+ "All files (*.*)\0" "*.*\0"
+ "Libraries (*.dll)\0" "*.dll\0"
+ "Programs\0" "*.exe\0"
+ "Symbol files\0" "*.ico;*.exe;*.dll\0"
+ "Symbols (*.ico)\0" "*.ico\0"
+};
diff --git a/programs/progman/TODO b/programs/progman/TODO
new file mode 100644
index 0000000..c3685a2
--- /dev/null
+++ b/programs/progman/TODO
@@ -0,0 +1,6 @@
+* Microsoft `*.grp' files use a checksum.
+ Find out how to calculate it.
+
+* Accelerators
+
+* Create some icons
diff --git a/programs/progman/Xx.rc b/programs/progman/Xx.rc
new file mode 100644
index 0000000..44d7991
--- /dev/null
+++ b/programs/progman/Xx.rc
@@ -0,0 +1,174 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid
+ */
+
+#include "progman.h"
+
+/* Menu */
+
+MENU_Xx MENU
+{
+ POPUP MENU_FILE {
+ MENUITEM MENU_FILE_NEW, PM_NEW
+ MENUITEM MENU_FILE_OPEN, PM_OPEN
+ MENUITEM MENU_FILE_MOVE, PM_MOVE, GRAYED
+ MENUITEM MENU_FILE_COPY, PM_COPY, GRAYED
+ MENUITEM MENU_FILE_DELETE, PM_DELETE
+ MENUITEM MENU_FILE_ATTRIBUTES, PM_ATTRIBUTES
+ MENUITEM SEPARATOR
+ MENUITEM MENU_FILE_EXECUTE, PM_EXECUTE
+ MENUITEM SEPARATOR
+ MENUITEM MENU_FILE_EXIT, PM_EXIT
+ }
+ POPUP MENU_OPTIONS {
+ MENUITEM MENU_OPTIONS_AUTO_ARRANGE, PM_AUTO_ARRANGE
+ MENUITEM MENU_OPTIONS_MIN_ON_RUN, PM_MIN_ON_RUN
+ MENUITEM MENU_OPTIONS_SAVE_SETTINGS, PM_SAVE_SETTINGS
+ }
+ POPUP MENU_WINDOWS {
+ MENUITEM MENU_WINDOWS_OVERLAP, PM_OVERLAP
+ MENUITEM MENU_WINDOWS_SIDE_BY_SIDE, PM_SIDE_BY_SIDE
+ MENUITEM MENU_WINDOWS_ARRANGE, PM_ARRANGE
+ }
+ POPUP MENU_LANGUAGE {
+ MENUITEM "&English", PM_En
+ MENUITEM "&Deutsch", PM_De
+ }
+ POPUP MENU_HELP {
+ MENUITEM MENU_HELP_CONTENTS, PM_CONTENTS
+ MENUITEM MENU_HELP_SEARCH, PM_SEARCH
+ MENUITEM SEPARATOR
+ MENUITEM MENU_HELP_HELP_ON_HELP, PM_HELPONHELP
+ MENUITEM MENU_HELP_TUTORIAL, PM_TUTORIAL
+ MENUITEM SEPARATOR
+
+ POPUP MENU_INFO {
+ MENUITEM MENU_INFO_LICENSE, PM_LICENSE
+ MENUITEM MENU_INFO_NO_WARRANTY, PM_NO_WARRANTY
+ MENUITEM MENU_INFO_ABOUT_WINE, PM_ABOUT_WINE
+ }
+ }
+}
+
+/* Dialog `New' */
+
+DIALOG_NEW_Xx DIALOG 0, 0, 170, 65
+STYLE DS_MODALFRAME
+CAPTION DIALOG_NEW_CAPTION
+{
+RADIOBUTTON "", PM_NEW_GROUP, 10, 15, 10, 15
+LTEXT DIALOG_NEW_GROUP, PM_NEW_GROUP, 20, 18, 80, 15
+RADIOBUTTON "", PM_NEW_PROGRAM, 10, 35, 10, 15
+LTEXT DIALOG_NEW_PROGRAM, PM_NEW_PROGRAM, 20, 38, 80, 15
+DEFPUSHBUTTON DIALOG_OK, IDOK, 105, 5, 60, 15
+PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 105, 25, 60, 15
+PUSHBUTTON DIALOG_HELP, PM_HELP, 105, 45, 60, 15
+}
+
+/* Dialog `Move' */
+
+DIALOG_MOVE_Xx DIALOG 0, 0, 250, 65
+STYLE DS_MODALFRAME
+CAPTION DIALOG_MOVE_CAPTION
+{
+LTEXT DIALOG_MOVE_PROGRAM, IDIGNORE, 5, 5, 90, 15
+LTEXT "", PM_PROGRAM, 95, 5, 90, 15
+LTEXT DIALOG_MOVE_FROM_GROUP, IDIGNORE, 5, 13, 90, 15
+LTEXT "", PM_FROM_GROUP, 95, 13, 90, 15
+LTEXT DIALOG_MOVE_TO_GROUP, PM_TO_GROUP_TXT, 5, 28, 140, 15
+COMBOBOX PM_TO_GROUP, 5, 38, 140, 50, CBS_DROPDOWNLIST
+DEFPUSHBUTTON DIALOG_OK, IDOK, 185, 5, 60, 15
+PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 185, 25, 60, 15
+PUSHBUTTON DIALOG_HELP, PM_HELP, 185, 45, 60, 15
+}
+
+/* Dialog `Copy' */
+
+DIALOG_COPY_Xx DIALOG 0, 0, 250, 65
+STYLE DS_MODALFRAME
+CAPTION DIALOG_COPY_CAPTION
+{
+LTEXT DIALOG_COPY_PROGRAM, IDIGNORE, 5, 5, 90, 15
+LTEXT "", PM_PROGRAM, 95, 5, 90, 15
+LTEXT DIALOG_COPY_FROM_GROUP, IDIGNORE, 5, 13, 90, 15
+LTEXT "", PM_FROM_GROUP, 95, 13, 90, 15
+LTEXT DIALOG_COPY_TO_GROUP, PM_TO_GROUP_TXT, 5, 28, 140, 15
+COMBOBOX PM_TO_GROUP, 5, 38, 140, 50, CBS_DROPDOWNLIST
+DEFPUSHBUTTON DIALOG_OK, IDOK, 185, 5, 60, 15
+PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 185, 25, 60, 15
+PUSHBUTTON DIALOG_HELP, PM_HELP, 185, 45, 60, 15
+}
+
+/* Dialog `Group attributes' */
+
+DIALOG_GROUP_Xx DIALOG 0, 0, 230, 65
+STYLE DS_MODALFRAME
+CAPTION DIALOG_GROUP_CAPTION
+{
+LTEXT DIALOG_GROUP_DESCRIPTION, PM_DESCRIPTION_TXT, 05, 18, 50, 10
+EDITTEXT PM_DESCRIPTION, 60, 18, 90, 15
+LTEXT DIALOG_GROUP_FILE, PM_FILE_TXT, 05, 38, 50, 10
+EDITTEXT PM_FILE, 60, 38, 90, 15
+DEFPUSHBUTTON DIALOG_OK, IDOK, 155, 5, 60, 15
+PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 155, 25, 60, 15
+PUSHBUTTON DIALOG_HELP, PM_HELP, 155, 45, 60, 15
+}
+
+/* Dialog `Program attributes' */
+
+DIALOG_PROGRAM_Xx DIALOG 0, 0, 250, 105
+STYLE DS_MODALFRAME
+CAPTION DIALOG_PROGRAM_CAPTION
+{
+LTEXT DIALOG_PROGRAM_DESCRIPTION, PM_DESCRIPTION_TXT, 05, 10, 60, 10
+EDITTEXT PM_DESCRIPTION, 80, 10, 90, 15
+LTEXT DIALOG_PROGRAM_COMMAND_LINE, PM_COMMAND_LINE_TXT, 05, 25, 60, 10
+EDITTEXT PM_COMMAND_LINE, 80, 25, 90, 15
+LTEXT DIALOG_PROGRAM_DIRECTORY, PM_DIRECTORY_TXT, 05, 40, 60, 10
+EDITTEXT PM_DIRECTORY, 80, 40, 90, 15
+LTEXT DIALOG_PROGRAM_HOT_KEY, PM_HOT_KEY_TXT, 05, 55, 60, 10
+EDITTEXT PM_HOT_KEY, 80, 55, 90, 15
+ICON "", PM_ICON, 20, 70
+CHECKBOX "", PM_SYMBOL, 80, 75, 10, 10
+LTEXT DIALOG_PROGRAM_SYMBOL, IDIGNORE, 95, 75, 75, 10
+DEFPUSHBUTTON DIALOG_OK, IDOK, 185, 5, 60, 15
+PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 185, 25, 60, 15
+PUSHBUTTON DIALOG_BROWSE, PM_BROWSE, 185, 45, 60, 15
+PUSHBUTTON DIALOG_PROGRAM_OTHER_SYMBOL, PM_OTHER_SYMBOL, 185, 65, 60, 15
+PUSHBUTTON DIALOG_HELP, PM_HELP, 185, 85, 60, 15
+}
+
+/* Dialog `Symbol' */
+
+DIALOG_SYMBOL_Xx DIALOG 0, 0, 200, 85
+STYLE DS_MODALFRAME
+CAPTION DIALOG_SYMBOL_CAPTION
+{
+LTEXT DIALOG_SYMBOL_FILE, PM_ICON_FILE_TXT, 5, 15, 40, 10
+EDITTEXT PM_ICON_FILE, 45, 15, 85, 15
+LTEXT DIALOG_SYMBOL_CURRENT, PM_SYMBOL_LIST_TXT, 5, 30, 125, 10
+COMBOBOX PM_SYMBOL_LIST, 5, 40, 125, 50,
+ CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | CBS_OWNERDRAWFIXED
+DEFPUSHBUTTON DIALOG_OK, IDOK, 135, 5, 60, 15
+PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 135, 25, 60, 15
+PUSHBUTTON DIALOG_BROWSE , PM_BROWSE, 135, 45, 60, 15
+PUSHBUTTON DIALOG_HELP, PM_HELP, 135, 65, 60, 15
+}
+
+/* Dialog `Execute' */
+
+DIALOG_EXECUTE_Xx DIALOG 0, 0, 200, 85
+STYLE DS_MODALFRAME
+CAPTION DIALOG_EXECUTE_CAPTION
+{
+LTEXT DIALOG_EXECUTE_COMMAND_LINE, IDIGNORE, 05, 15, 120, 10
+EDITTEXT PM_COMMAND, 05, 25, 120, 15
+CHECKBOX "", PM_SYMBOL, 05, 45, 10, 10
+LTEXT DIALOG_EXECUTE_SYMBOL, IDIGNORE, 20, 45, 120, 10
+DEFPUSHBUTTON DIALOG_OK, IDOK, 135, 5, 60, 15
+PUSHBUTTON DIALOG_CANCEL, IDCANCEL, 135, 25, 60, 15
+PUSHBUTTON DIALOG_BROWSE , PM_BROWSE, 135, 45, 60, 15
+PUSHBUTTON DIALOG_HELP, PM_HELP, 135, 65, 60, 15
+}
diff --git a/programs/progman/accel.rc b/programs/progman/accel.rc
new file mode 100644
index 0000000..3409682
--- /dev/null
+++ b/programs/progman/accel.rc
@@ -0,0 +1,6 @@
+#include "progman.h"
+
+ACCEL ACCELERATORS
+{
+VK_RETURN, PM_EXECUTE, VIRTKEY, ALT
+}
diff --git a/programs/progman/dialog.c b/programs/progman/dialog.c
new file mode 100644
index 0000000..c19ca83
--- /dev/null
+++ b/programs/progman/dialog.c
@@ -0,0 +1,569 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid
+ */
+
+#include <windows.h>
+#include <commdlg.h>
+#include "progman.h"
+
+static BOOL DIALOG_Browse(HWND, LPCSTR, LPSTR, INT);
+static LRESULT DIALOG_NEW_DlgProc(HWND, UINT, WPARAM, LPARAM);
+static LRESULT DIALOG_COPY_MOVE_DlgProc(HWND, UINT, WPARAM, LPARAM);
+static LRESULT DIALOG_GROUP_DlgProc(HWND, UINT, WPARAM, LPARAM);
+static LRESULT DIALOG_PROGRAM_DlgProc(HWND, UINT, WPARAM, LPARAM);
+static LRESULT DIALOG_SYMBOL_DlgProc(HWND, UINT, WPARAM, LPARAM);
+static LRESULT DIALOG_EXECUTE_DlgProc(HWND, UINT, WPARAM, LPARAM);
+
+/***********************************************************************
+ *
+ * DIALOG_New
+ */
+
+static struct
+{
+ INT nDefault;
+} New;
+
+INT DIALOG_New(INT nDefault)
+{
+ WNDPROC lpfnDlg = MakeProcInstance(DIALOG_NEW_DlgProc, Globals.hInstance);
+ INT ret;
+
+ New.nDefault = nDefault;
+
+ ret = DialogBox(Globals.hInstance, STRING_NEW_Xx,
+ Globals.hMainWnd, lpfnDlg);
+ FreeProcInstance(lpfnDlg);
+ return ret;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * DIALOG_NEW_DlgProc
+ */
+
+static LRESULT DIALOG_NEW_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ CheckRadioButton(hDlg, PM_NEW_GROUP, PM_NEW_PROGRAM, New.nDefault);
+ break;
+
+ case WM_COMMAND:
+ switch (wParam)
+ {
+ case PM_NEW_GROUP:
+ case PM_NEW_PROGRAM:
+ CheckRadioButton(hDlg, PM_NEW_GROUP, PM_NEW_PROGRAM, wParam);
+ return TRUE;
+
+ case IDOK:
+ EndDialog(hDlg, IsDlgButtonChecked(hDlg, PM_NEW_GROUP) ?
+ PM_NEW_GROUP : PM_NEW_PROGRAM);
+ return TRUE;
+
+ case IDCANCEL:
+ EndDialog(hDlg, IDCANCEL);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/***********************************************************************
+ *
+ * DIALOG_CopyMove
+ */
+
+static struct
+{
+ LPCSTR lpszProgramName, lpszFromGroupName;
+ HLOCAL hToGroup;
+} CopyMove;
+
+HLOCAL DIALOG_CopyMove(LPCSTR lpszProgramName, LPCSTR lpszFromGroupName,
+ BOOL bMove)
+{
+ WNDPROC lpfnDlg = MakeProcInstance(DIALOG_COPY_MOVE_DlgProc, Globals.hInstance);
+ INT ret;
+
+ CopyMove.lpszProgramName = lpszProgramName;
+ CopyMove.lpszFromGroupName = lpszFromGroupName;
+ CopyMove.hToGroup = 0;
+
+ ret = DialogBox(Globals.hInstance,
+ bMove ? STRING_MOVE_Xx : STRING_COPY_Xx,
+ Globals.hMainWnd, lpfnDlg);
+ FreeProcInstance(lpfnDlg);
+
+ return((ret == IDOK) ? CopyMove.hToGroup : 0);
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * DIALOG_COPY_MOVE_DlgProc
+ */
+
+static LRESULT DIALOG_COPY_MOVE_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ HLOCAL hGroup;
+
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ /* List all group names */
+ for (hGroup = GROUP_FirstGroup(); hGroup; hGroup = GROUP_NextGroup(hGroup))
+ SendDlgItemMessage(hDlg, PM_TO_GROUP, CB_ADDSTRING, 0,
+ (LPARAM) GROUP_GroupName(hGroup));
+
+ SetDlgItemText(hDlg, PM_PROGRAM, (LPSTR)CopyMove.lpszProgramName);
+ SetDlgItemText(hDlg, PM_FROM_GROUP, (LPSTR)CopyMove.lpszFromGroupName);
+ break;
+
+ case WM_COMMAND:
+ switch (wParam)
+ {
+ case IDOK:
+ {
+ /* Get selected group */
+ INT nCurSel = SendDlgItemMessage(hDlg, PM_TO_GROUP, CB_GETCURSEL, 0, 0);
+ INT nLen = SendDlgItemMessage(hDlg, PM_TO_GROUP, CB_GETLBTEXTLEN, nCurSel, 0);
+ HLOCAL hBuffer = LocalAlloc(LMEM_FIXED, nLen + 1);
+ LPSTR buffer = LocalLock(hBuffer);
+
+ SendDlgItemMessage(hDlg, PM_TO_GROUP, CB_GETLBTEXT, nCurSel, (LPARAM)buffer);
+ for (hGroup = GROUP_FirstGroup(); hGroup; hGroup = GROUP_NextGroup(hGroup))
+ if (!lstrcmp(buffer, GROUP_GroupName(hGroup))) break;
+ LocalFree(hBuffer);
+
+ CopyMove.hToGroup = hGroup;
+ EndDialog(hDlg, IDOK);
+ return TRUE;
+ }
+
+ case IDCANCEL:
+ EndDialog(hDlg, IDCANCEL);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/***********************************************************************
+ *
+ * DIALOG_Delete
+ */
+
+BOOL DIALOG_Delete(LPCSTR lpszFormat_s, LPCSTR lpszName)
+{
+ CHAR msg[1000];
+ if (sizeof(msg) <= lstrlen(lpszFormat_s) + lstrlen(lpszName)) return FALSE;
+ wsprintf(msg, (LPSTR)lpszFormat_s, lpszName);
+ return (IDYES == MessageBox(Globals.hMainWnd, msg, STRING_DELETE,
+ MB_YESNO | MB_DEFBUTTON2));
+}
+
+
+/***********************************************************************
+ *
+ * DIALOG_GroupAttributes
+ */
+
+static struct
+{
+ LPSTR lpszTitle, lpszGrpFile;
+ INT nSize;
+} GroupAttributes;
+
+BOOL DIALOG_GroupAttributes(LPSTR lpszTitle, LPSTR lpszGrpFile, INT nSize)
+{
+ WNDPROC lpfnDlg = MakeProcInstance(DIALOG_GROUP_DlgProc, Globals.hInstance);
+ INT ret;
+
+ GroupAttributes.nSize = nSize;
+ GroupAttributes.lpszTitle = lpszTitle;
+ GroupAttributes.lpszGrpFile = lpszGrpFile;
+
+ ret = DialogBox(Globals.hInstance, STRING_GROUP_Xx,
+ Globals.hMainWnd, lpfnDlg);
+ FreeProcInstance(lpfnDlg);
+ return(ret == IDOK);
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * DIALOG_GROUP_DlgProc
+ */
+
+static LRESULT DIALOG_GROUP_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ SetDlgItemText(hDlg, PM_DESCRIPTION, GroupAttributes.lpszTitle);
+ SetDlgItemText(hDlg, PM_FILE, GroupAttributes.lpszGrpFile);
+ break;
+
+ case WM_COMMAND:
+ switch (wParam)
+ {
+ case IDOK:
+ GetDlgItemText(hDlg, PM_DESCRIPTION, GroupAttributes.lpszTitle,
+ GroupAttributes.nSize);
+ GetDlgItemText(hDlg, PM_FILE, GroupAttributes.lpszGrpFile,
+ GroupAttributes.nSize);
+ EndDialog(hDlg, IDOK);
+ return TRUE;
+
+ case IDCANCEL:
+ EndDialog(hDlg, IDCANCEL);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/***********************************************************************
+ *
+ * DIALOG_ProgramAttributes
+ */
+
+static struct
+{
+ LPSTR lpszTitle, lpszCmdLine, lpszWorkDir, lpszIconFile, lpszTmpIconFile;
+ INT nSize;
+ INT *lpnCmdShow;
+ INT *lpnHotKey;
+ HWND hSelGroupWnd;
+ HICON *lphIcon, hTmpIcon;
+ INT *lpnIconIndex, nTmpIconIndex;
+} ProgramAttributes;
+
+BOOL DIALOG_ProgramAttributes(LPSTR lpszTitle, LPSTR lpszCmdLine,
+ LPSTR lpszWorkDir, LPSTR lpszIconFile,
+ HICON *lphIcon, INT *lpnIconIndex,
+ INT *lpnHotKey, INT *lpnCmdShow, INT nSize)
+{
+ CHAR szTmpIconFile[MAX_PATHNAME_LEN];
+ WNDPROC lpfnDlg = MakeProcInstance(DIALOG_PROGRAM_DlgProc, Globals.hInstance);
+ INT ret;
+
+ ProgramAttributes.nSize = nSize;
+ ProgramAttributes.lpszTitle = lpszTitle;
+ ProgramAttributes.lpszCmdLine = lpszCmdLine;
+ ProgramAttributes.lpszWorkDir = lpszWorkDir;
+ ProgramAttributes.lpszIconFile = lpszIconFile;
+ ProgramAttributes.lpnCmdShow = lpnCmdShow;
+ ProgramAttributes.lpnHotKey = lpnHotKey;
+ ProgramAttributes.lphIcon = lphIcon;
+ ProgramAttributes.lpnIconIndex = lpnIconIndex;
+
+#if 0
+ ProgramAttributes.hTmpIcon = 0;
+#else
+ ProgramAttributes.hTmpIcon = *lphIcon;
+#endif
+ ProgramAttributes.nTmpIconIndex = *lpnIconIndex;
+ ProgramAttributes.lpszTmpIconFile = szTmpIconFile;
+ lstrcpyn(ProgramAttributes.lpszTmpIconFile, lpszIconFile, MAX_PATHNAME_LEN);
+
+ ret = DialogBox(Globals.hInstance, STRING_PROGRAM_Xx,
+ Globals.hMainWnd, lpfnDlg);
+ FreeProcInstance(lpfnDlg);
+
+ return(ret == IDOK);
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * DIALOG_PROGRAM_DlgProc
+ */
+
+static LRESULT DIALOG_PROGRAM_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ SetDlgItemText(hDlg, PM_DESCRIPTION, ProgramAttributes.lpszTitle);
+ SetDlgItemText(hDlg, PM_COMMAND_LINE, ProgramAttributes.lpszCmdLine);
+ SetDlgItemText(hDlg, PM_DIRECTORY, ProgramAttributes.lpszWorkDir);
+ if (!*ProgramAttributes.lpnHotKey)
+ SetDlgItemText(hDlg, PM_HOT_KEY, (LPSTR)STRING_NO_HOT_KEY);
+
+ CheckDlgButton(hDlg, PM_SYMBOL,
+ (*ProgramAttributes.lpnCmdShow == SW_SHOWMINIMIZED));
+ SendDlgItemMessage(hDlg, PM_ICON, STM_SETICON,
+ (WPARAM) ProgramAttributes.hTmpIcon, 0);
+ break;
+
+ case WM_COMMAND:
+ switch (wParam)
+ {
+ case PM_SYMBOL:
+ CheckDlgButton(hDlg, PM_SYMBOL, !IsDlgButtonChecked(hDlg, PM_SYMBOL));
+ return TRUE;
+
+ case PM_BROWSE:
+ {
+ CHAR filename[MAX_PATHNAME_LEN];
+ if (DIALOG_Browse(hDlg, STRING_BROWSE_EXE_FILTER,
+ filename, sizeof(filename)))
+ SetDlgItemText(hDlg, PM_COMMAND_LINE, filename);
+ return TRUE;
+ }
+
+ case PM_OTHER_SYMBOL:
+ {
+ DIALOG_Symbol(&ProgramAttributes.hTmpIcon,
+ ProgramAttributes.lpszTmpIconFile,
+ &ProgramAttributes.nTmpIconIndex,
+ MAX_PATHNAME_LEN);
+
+ SendDlgItemMessage(hDlg, PM_ICON, STM_SETICON,
+ (WPARAM) ProgramAttributes.hTmpIcon, 0);
+ return TRUE;
+ }
+
+ case IDOK:
+ GetDlgItemText(hDlg, PM_DESCRIPTION,
+ ProgramAttributes.lpszTitle,
+ ProgramAttributes.nSize);
+ GetDlgItemText(hDlg, PM_COMMAND_LINE,
+ ProgramAttributes.lpszCmdLine,
+ ProgramAttributes.nSize);
+ GetDlgItemText(hDlg, PM_DIRECTORY,
+ ProgramAttributes.lpszWorkDir,
+ ProgramAttributes.nSize);
+
+ if (ProgramAttributes.hTmpIcon)
+ {
+#if 0
+ if (*ProgramAttributes.lphIcon)
+ DestroyIcon(*ProgramAttributes.lphIcon);
+#endif
+ *ProgramAttributes.lphIcon = ProgramAttributes.hTmpIcon;
+ *ProgramAttributes.lpnIconIndex = ProgramAttributes.nTmpIconIndex;
+ lstrcpyn(ProgramAttributes.lpszIconFile,
+ ProgramAttributes.lpszTmpIconFile,
+ ProgramAttributes.nSize);
+ }
+
+ *ProgramAttributes.lpnCmdShow =
+ IsDlgButtonChecked(hDlg, PM_SYMBOL) ?
+ SW_SHOWMINIMIZED : SW_SHOWNORMAL;
+ EndDialog(hDlg, IDOK);
+ return TRUE;
+
+ case IDCANCEL:
+ EndDialog(hDlg, IDCANCEL);
+ return TRUE;
+ }
+ return FALSE;
+ }
+ return FALSE;
+}
+
+/***********************************************************************
+ *
+ * DIALOG_Symbol
+ */
+
+static struct
+{
+ LPSTR lpszIconFile;
+ INT nSize;
+ HICON *lphIcon;
+ INT *lpnIconIndex;
+} Symbol;
+
+VOID DIALOG_Symbol(HICON *lphIcon, LPSTR lpszIconFile,
+ INT *lpnIconIndex, INT nSize)
+{
+ WNDPROC lpfnDlg = MakeProcInstance(DIALOG_SYMBOL_DlgProc, Globals.hInstance);
+
+ Symbol.nSize = nSize;
+ Symbol.lpszIconFile = lpszIconFile;
+ Symbol.lphIcon = lphIcon;
+ Symbol.lpnIconIndex = lpnIconIndex;
+
+ DialogBox(Globals.hInstance, STRING_SYMBOL_Xx,
+ Globals.hMainWnd, lpfnDlg);
+ FreeProcInstance(lpfnDlg);
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * DIALOG_SYMBOL_DlgProc
+ */
+
+static LRESULT DIALOG_SYMBOL_DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ SetDlgItemText(hDlg, PM_ICON_FILE, Symbol.lpszIconFile);
+ SendDlgItemMessage(hDlg, PM_SYMBOL_LIST, CB_SETITEMHEIGHT, 0, (LPARAM) 32);
+ SendDlgItemMessage(hDlg, PM_SYMBOL_LIST, CB_ADDSTRING, 0, (LPARAM)*Symbol.lphIcon);
+ SendDlgItemMessage(hDlg, PM_SYMBOL_LIST, CB_ADDSTRING, 0, (LPARAM)Globals.hDefaultIcon);
+ SendDlgItemMessage(hDlg, PM_SYMBOL_LIST, CB_SETCURSEL, 0, 0);
+ return TRUE;
+
+ case WM_MEASUREITEM:
+ {
+ PMEASUREITEMSTRUCT measure = (PMEASUREITEMSTRUCT) lParam;
+ measure->itemWidth = 32;
+ measure->itemHeight = 32;
+ return TRUE;
+ }
+
+ case WM_DRAWITEM:
+ {
+ PDRAWITEMSTRUCT dis = (PDRAWITEMSTRUCT) lParam;
+ DrawIcon(dis->hDC, dis->rcItem.left, dis->rcItem.top, (HICON)dis->itemData);
+ return TRUE;
+ }
+
+ case WM_COMMAND:
+ switch (wParam)
+ {
+ case PM_BROWSE:
+ {
+ CHAR filename[MAX_PATHNAME_LEN];
+ if (DIALOG_Browse(hDlg, STRING_BROWSE_ICO_FILTER,
+ filename, sizeof(filename)))
+ SetDlgItemText(hDlg, PM_ICON_FILE, filename);
+ return TRUE;
+ }
+
+ case PM_HELP:
+ MAIN_NotImplementedError();
+ return TRUE;
+
+ case IDOK:
+ {
+ INT nCurSel = SendDlgItemMessage(hDlg, PM_SYMBOL_LIST, CB_GETCURSEL, 0, 0);
+
+ GetDlgItemText(hDlg, PM_ICON_FILE, Symbol.lpszIconFile, Symbol.nSize);
+
+ *Symbol.lphIcon = (HICON)SendDlgItemMessage(hDlg, PM_SYMBOL_LIST,
+ CB_GETITEMDATA,
+ (WPARAM) nCurSel, 0);
+#if 0
+ *Symbol.lphIcon = CopyIcon(*Symbol.lphIcon);
+#endif
+
+ EndDialog(hDlg, IDOK);
+ return TRUE;
+ }
+
+ case IDCANCEL:
+ EndDialog(hDlg, IDCANCEL);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/***********************************************************************
+ *
+ * DIALOG_Execute
+ */
+
+VOID DIALOG_Execute()
+{
+ WNDPROC lpfnDlg = MakeProcInstance(DIALOG_EXECUTE_DlgProc, Globals.hInstance);
+ DialogBox(Globals.hInstance, STRING_EXECUTE_Xx,
+ Globals.hMainWnd, lpfnDlg);
+ FreeProcInstance(lpfnDlg);
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * DIALOG_EXECUTE_DlgProc
+ */
+
+static LRESULT DIALOG_EXECUTE_DlgProc(HWND hDlg, UINT msg,
+ WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_COMMAND:
+ switch (wParam)
+ {
+ case PM_SYMBOL:
+ CheckDlgButton(hDlg, PM_SYMBOL, !IsDlgButtonChecked(hDlg, PM_SYMBOL));
+ return TRUE;
+
+ case PM_BROWSE:
+ {
+ CHAR filename[MAX_PATHNAME_LEN];
+ if (DIALOG_Browse(hDlg, STRING_BROWSE_EXE_FILTER,
+ filename, sizeof(filename)))
+ SetDlgItemText(hDlg, PM_COMMAND, filename);
+ return TRUE;
+ }
+
+ case PM_HELP:
+ MAIN_NotImplementedError();
+ return TRUE;
+
+ case IDOK:
+ {
+ CHAR cmdline[MAX_PATHNAME_LEN];
+ GetDlgItemText(hDlg, PM_COMMAND, cmdline, sizeof(cmdline));
+
+ WinExec(cmdline, IsDlgButtonChecked(hDlg, PM_SYMBOL) ?
+ SW_SHOWMINIMIZED : SW_SHOWNORMAL);
+ if (Globals.bMinOnRun) CloseWindow(Globals.hMainWnd);
+
+ EndDialog(hDlg, IDOK);
+ return TRUE;
+ }
+
+ case IDCANCEL:
+ EndDialog(hDlg, IDCANCEL);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/***********************************************************************
+ *
+ * DIALOG_Browse
+ */
+
+/* FIXME is this correct ? */
+static BOOL DIALOG_Browse(HWND hDlg, LPCSTR lpcstrFilter,
+ LPSTR lpstrFile, INT nMaxFile)
+{
+ OPENFILENAME openfilename;
+ openfilename.lStructSize = 0;
+ openfilename.hwndOwner = hDlg;
+ openfilename.hInstance = Globals.hInstance;
+ openfilename.lpstrFilter = (LPSTR)lpcstrFilter;
+ openfilename.lpstrCustomFilter = 0;
+ openfilename.nMaxCustFilter = 0;
+ openfilename.nFilterIndex = 0;
+ openfilename.lpstrFile = lpstrFile;
+ openfilename.nMaxFile = sizeof(lpstrFile);
+ openfilename.lpstrFileTitle = 0;
+ openfilename.nMaxFileTitle = 0;
+ openfilename.lpstrInitialDir = 0;
+ openfilename.lpstrTitle = 0;
+ openfilename.Flags = 0;
+ openfilename.nFileOffset = 0;
+ openfilename.nFileExtension = 0;
+ openfilename.lpstrDefExt = 0;
+ openfilename.lCustData = 0;
+ openfilename.lpfnHook = 0;
+ openfilename.lpTemplateName = 0;
+ return GetOpenFileName(&openfilename);
+}
+
+/* Local Variables: */
+/* c-file-style: "GNU" */
+/* End: */
diff --git a/programs/progman/group.c b/programs/progman/group.c
new file mode 100644
index 0000000..0646f8f
--- /dev/null
+++ b/programs/progman/group.c
@@ -0,0 +1,313 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid
+ */
+
+#include <stdio.h>
+#include <windows.h>
+#include "progman.h"
+
+/***********************************************************************
+ *
+ * GROUP_GroupWndProc
+ */
+
+static LRESULT GROUP_GroupWndProc (HWND hWnd, UINT msg,
+ WPARAM wParam, LPARAM lParam)
+{
+#if 0
+ printf("G %4.4x %4.4x\n", msg, wParam);
+#endif
+ switch (msg)
+ {
+ case WM_SYSCOMMAND:
+ if (wParam == SC_CLOSE) wParam = SC_MINIMIZE;
+ break;
+
+ case WM_CHILDACTIVATE:
+ case WM_NCLBUTTONDOWN:
+ Globals.hActiveGroup = (HLOCAL) GetWindowLong(hWnd, 0);
+ EnableMenuItem(Globals.hFileMenu, PM_MOVE , MF_GRAYED);
+ EnableMenuItem(Globals.hFileMenu, PM_COPY , MF_GRAYED);
+ break;
+ }
+ return(DefMDIChildProc(hWnd, msg, wParam, lParam));
+}
+
+/***********************************************************************
+ *
+ * GROUP_RegisterGroupWinClass
+ */
+
+ATOM GROUP_RegisterGroupWinClass()
+{
+ WNDCLASS class;
+
+ class.style = CS_HREDRAW | CS_VREDRAW;
+ class.lpfnWndProc = GROUP_GroupWndProc;
+ class.cbClsExtra = 0;
+ class.cbWndExtra = sizeof(LONG);
+ class.hInstance = Globals.hInstance;
+ class.hIcon = LoadIcon (0, MAKEINTRESOURCE(OIC_WINEICON));
+ class.hCursor = LoadCursor (0, IDC_ARROW);
+ class.hbrBackground = GetStockObject (WHITE_BRUSH);
+ class.lpszMenuName = 0;
+ class.lpszClassName = STRING_GROUP_WIN_CLASS_NAME;
+
+ return RegisterClass(&class);
+}
+
+/***********************************************************************
+ *
+ * GROUP_NewGroup
+ */
+
+VOID GROUP_NewGroup()
+{
+ CHAR szName[MAX_PATHNAME_LEN] = "";
+ CHAR szFile[MAX_PATHNAME_LEN] = "";
+ OFSTRUCT dummy;
+
+ if (!DIALOG_GroupAttributes(szName, szFile, MAX_PATHNAME_LEN)) return;
+
+ if (OpenFile(szFile, &dummy, OF_EXIST) == HFILE_ERROR)
+ {
+ /* File doesn't exist */
+ HLOCAL hGroup =
+ GROUP_AddGroup(szName, szFile, SW_SHOWNORMAL,
+ DEF_GROUP_WIN_XPOS, DEF_GROUP_WIN_YPOS,
+ DEF_GROUP_WIN_WIDTH, DEF_GROUP_WIN_HEIGHT, 0, 0,
+ FALSE, FALSE, FALSE);
+ if (!hGroup) return;
+ GRPFILE_WriteGroupFile(hGroup);
+ }
+ else /* File exist */
+ GRPFILE_ReadGroupFile(szFile);
+
+ /* FIXME Update progman.ini */
+}
+
+/***********************************************************************
+ *
+ * GROUP_AddGroup
+ */
+
+HLOCAL GROUP_AddGroup(LPCSTR lpszName, LPCSTR lpszGrpFile, INT nCmdShow,
+ INT x, INT y, INT width, INT height,
+ INT iconx, INT icony,
+ BOOL bFileNameModified, BOOL bOverwriteFileOk,
+ /* FIXME shouldn't be necessary */
+ BOOL bSuppressShowWindow)
+{
+ GROUP *group, *prior;
+ MDICREATESTRUCT cs;
+ INT seqnum;
+ HLOCAL hPrior, *p;
+ HLOCAL hGroup = LocalAlloc(LMEM_FIXED, sizeof(GROUP));
+ HLOCAL hName = LocalAlloc(LMEM_FIXED, 1 + lstrlen(lpszName));
+ HLOCAL hGrpFile = LocalAlloc(LMEM_FIXED, 1 + lstrlen(lpszGrpFile));
+ if (!hGroup || !hName || !hGrpFile)
+ {
+ MessageBox(Globals.hMainWnd, "out of memory", lpszName, MB_OK);
+ if (hGroup) LocalFree(hGroup);
+ if (hName) LocalFree(hName);
+ if (hGrpFile) LocalFree(hGrpFile);
+ return(0);
+ }
+ hmemcpy(LocalLock(hName), lpszName, 1 + lstrlen(lpszName));
+ hmemcpy(LocalLock(hGrpFile), lpszGrpFile, 1 + lstrlen(lpszGrpFile));
+
+ Globals.hActiveGroup = hGroup;
+
+ seqnum = 1;
+ hPrior = 0;
+ p = &Globals.hGroups;
+ while (*p)
+ {
+ hPrior = *p;
+ prior = LocalLock(hPrior);
+ p = &prior->hNext;
+ if (prior->seqnum >= seqnum)
+ seqnum = prior->seqnum + 1;
+ }
+ *p = hGroup;
+
+ group = LocalLock(hGroup);
+ group->hPrior = hPrior;
+ group->hNext = 0;
+ group->hName = hName;
+ group->hGrpFile = hGrpFile;
+ group->bFileNameModified = bFileNameModified;
+ group->bOverwriteFileOk = bOverwriteFileOk;
+ group->seqnum = seqnum;
+ group->nCmdShow = nCmdShow;
+ group->x = x;
+ group->y = y;
+ group->width = width;
+ group->height = height;
+ group->iconx = iconx;
+ group->icony = icony;
+ group->hPrograms = 0;
+ group->hActiveProgram = 0;
+
+ cs.szClass = STRING_GROUP_WIN_CLASS_NAME;
+ cs.szTitle = (LPSTR)lpszName;
+ cs.hOwner = 0;
+ cs.x = x;
+ cs.y = y;
+ cs.cx = width;
+ cs.cy = height;
+ cs.style = 0;
+ cs.lParam = 0;
+
+ group->hWnd = (HWND)SendMessage(Globals.hMDIWnd, WM_MDICREATE, 0, (LPARAM)&cs);
+
+ SetWindowLong(group->hWnd, 0, (LONG) hGroup);
+
+#if 1
+ if (!bSuppressShowWindow) /* FIXME shouldn't be necessary */
+#endif
+ {
+ ShowWindow (group->hWnd, nCmdShow);
+ UpdateWindow (group->hWnd);
+ }
+
+ return(hGroup);
+}
+
+/***********************************************************************
+ *
+ * GROUP_ModifyGroup
+ */
+
+VOID GROUP_ModifyGroup(HLOCAL hGroup)
+{
+ GROUP *group = LocalLock(hGroup);
+ CHAR szName[MAX_PATHNAME_LEN];
+ CHAR szFile[MAX_PATHNAME_LEN];
+ lstrcpyn(szName, LocalLock(group->hName), MAX_PATHNAME_LEN);
+ lstrcpyn(szFile, LocalLock(group->hGrpFile), MAX_PATHNAME_LEN);
+
+ if (!DIALOG_GroupAttributes(szName, szFile, MAX_PATHNAME_LEN)) return;
+
+ if (strcmp(szFile, LocalLock(group->hGrpFile)))
+ group->bOverwriteFileOk = FALSE;
+
+ MAIN_ReplaceString(&group->hName, szName);
+ MAIN_ReplaceString(&group->hGrpFile, szFile);
+
+ GRPFILE_WriteGroupFile(hGroup);
+
+ /* FIXME Delete old GrpFile if GrpFile changed */
+
+ /* FIXME Update progman.ini */
+
+ SetWindowText(group->hWnd, szName);
+}
+
+/***********************************************************************
+ *
+ * GROUP_ShowGroupWindow
+ */
+
+/* FIXME shouldn't be necessary */
+VOID GROUP_ShowGroupWindow(HLOCAL hGroup)
+{
+ GROUP *group = LocalLock(hGroup);
+ ShowWindow (group->hWnd, group->nCmdShow);
+ UpdateWindow (group->hWnd);
+}
+
+/***********************************************************************
+ *
+ * GROUP_DeleteGroup
+ */
+
+VOID GROUP_DeleteGroup(HLOCAL hGroup)
+{
+ GROUP *group = LocalLock(hGroup);
+
+ Globals.hActiveGroup = 0;
+
+ if (group->hPrior)
+ ((GROUP*)LocalLock(group->hPrior))->hNext = group->hNext;
+ else Globals.hGroups = group->hNext;
+
+ if (group->hNext)
+ ((GROUP*)LocalLock(group->hNext))->hPrior = group->hPrior;
+
+ while (group->hPrograms)
+ PROGRAM_DeleteProgram(group->hPrograms, FALSE);
+
+ /* FIXME Update progman.ini */
+
+ SendMessage(Globals.hMDIWnd, WM_MDIDESTROY, (WPARAM)group->hWnd, 0);
+
+ LocalFree(group->hName);
+ LocalFree(group->hGrpFile);
+ LocalFree(hGroup);
+}
+
+/***********************************************************************
+ *
+ * GROUP_FirstGroup
+ */
+
+HLOCAL GROUP_FirstGroup()
+{
+ return(Globals.hGroups);
+}
+
+/***********************************************************************
+ *
+ * GROUP_NextGroup
+ */
+
+HLOCAL GROUP_NextGroup(HLOCAL hGroup)
+{
+ GROUP *group;
+ if (!hGroup) return(0);
+ group = LocalLock(hGroup);
+ return(group->hNext);
+}
+
+/***********************************************************************
+ *
+ * GROUP_ActiveGroup
+ */
+
+HLOCAL GROUP_ActiveGroup()
+{
+ return(Globals.hActiveGroup);
+}
+
+/***********************************************************************
+ *
+ * GROUP_GroupWnd
+ */
+
+HWND GROUP_GroupWnd(HLOCAL hGroup)
+{
+ GROUP *group;
+ if (!hGroup) return(0);
+ group = LocalLock(hGroup);
+ return(group->hWnd);
+}
+
+/***********************************************************************
+ *
+ * GROUP_GroupName
+ */
+
+LPCSTR GROUP_GroupName(HLOCAL hGroup)
+{
+ GROUP *group;
+ if (!hGroup) return(0);
+ group = LocalLock(hGroup);
+ return(LocalLock(group->hName));
+}
+
+/* Local Variables: */
+/* c-file-style: "GNU" */
+/* End: */
diff --git a/programs/progman/grpfile.c b/programs/progman/grpfile.c
new file mode 100644
index 0000000..50e99ec
--- /dev/null
+++ b/programs/progman/grpfile.c
@@ -0,0 +1,645 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid
+ */
+
+#include <windows.h>
+#include "progman.h"
+
+#define MALLOCHUNK 1000
+
+#define GET_USHORT(buffer, i)\
+ (((BYTE)((buffer)[(i)]) + 0x100 * (BYTE)((buffer)[(i)+1])))
+#define GET_SHORT(buffer, i)\
+ (((BYTE)((buffer)[(i)]) + 0x100 * (signed char)((buffer)[(i)+1])))
+#define PUT_SHORT(buffer, i, s)\
+ (((buffer)[(i)] = (s) & 0xff, (buffer)[(i)+1] = ((s) >> 8) & 0xff))
+
+static BOOL GRPFILE_ReadFileToBuffer(LPCSTR, HLOCAL*, INT*);
+static HLOCAL GRPFILE_ScanGroup(LPCSTR, INT, LPCSTR, BOOL);
+static HLOCAL GRPFILE_ScanProgram(LPCSTR, INT, LPCSTR, INT,
+ LPCSTR, HLOCAL,LPCSTR);
+static BOOL GRPFILE_DoWriteGroupFile(HFILE file, GROUP *group);
+
+/***********************************************************************
+ *
+ * GRPFILE_ModifyFileName
+ *
+ * Change extension `.grp' to `.gr'
+ */
+
+static VOID GRPFILE_ModifyFileName(LPSTR lpszNewName, LPCSTR lpszOrigName,
+ INT nSize, BOOL bModify)
+{
+ lstrcpyn(lpszNewName, lpszOrigName, nSize);
+ lpszNewName[nSize-1] = '\0';
+ if (!bModify) return;
+ if (!lstrcmpi(lpszNewName + strlen(lpszNewName) - 4, ".grp"))
+ lpszNewName[strlen(lpszNewName) - 1] = '\0';
+}
+
+/***********************************************************************
+ *
+ * GRPFILE_ReadGroupFile
+ */
+
+HLOCAL GRPFILE_ReadGroupFile(LPCSTR lpszPath)
+{
+ CHAR szPath_gr[MAX_PATHNAME_LEN];
+ BOOL bFileNameModified = FALSE;
+ OFSTRUCT dummy;
+ HLOCAL hBuffer, hGroup;
+ INT size;
+
+ /* if `.gr' file exists use that */
+ GRPFILE_ModifyFileName(szPath_gr, lpszPath, MAX_PATHNAME_LEN, TRUE);
+ if (OpenFile(szPath_gr, &dummy, OF_EXIST) != HFILE_ERROR)
+ {
+ lpszPath = szPath_gr;
+ bFileNameModified = TRUE;
+ }
+
+ /* Read the whole file into a buffer */
+ if (!GRPFILE_ReadFileToBuffer(lpszPath, &hBuffer, &size))
+ {
+ MAIN_GrpFileReadError(lpszPath);
+ return(0);
+ }
+
+ /* Interpret buffer */
+ hGroup = GRPFILE_ScanGroup(LocalLock(hBuffer), size,
+ lpszPath, bFileNameModified);
+ if (!hGroup) MAIN_GrpFileReadError(lpszPath);
+
+ LocalFree(hBuffer);
+
+ return(hGroup);
+}
+
+/***********************************************************************
+ *
+ * GRPFILE_ReadFileToBuffer
+ */
+
+static BOOL GRPFILE_ReadFileToBuffer(LPCSTR path, HLOCAL *phBuffer,
+ INT *piSize)
+{
+ INT len, size;
+ LPSTR buffer;
+ HLOCAL hBuffer, hNewBuffer;
+ HFILE file;
+
+ file=_lopen(path, OF_READ);
+ if (file == HFILE_ERROR) return FALSE;
+
+ size = 0;
+ hBuffer = LocalAlloc(LMEM_FIXED, size + MALLOCHUNK + 1);
+ if (!hBuffer) return FALSE;
+ buffer = LocalLock(hBuffer);
+
+ while ((len = _lread(file, buffer + size, MALLOCHUNK))
+ == MALLOCHUNK)
+ {
+ size += len;
+ hNewBuffer = LocalReAlloc(hBuffer, size + MALLOCHUNK + 1,
+ LMEM_FIXED);
+ if (!hNewBuffer)
+ {
+ LocalFree(hBuffer);
+ return FALSE;
+ }
+ hBuffer = hNewBuffer;
+ buffer = LocalLock(hBuffer);
+ }
+
+ _lclose(file);
+
+ if (len == HFILE_ERROR)
+ {
+ LocalFree(hBuffer);
+ return FALSE;
+ }
+
+ size += len;
+ buffer[size] = 0;
+
+ *phBuffer = hBuffer;
+ *piSize = size;
+ return TRUE;
+}
+
+/***********************************************************************
+ * GRPFILE_ScanGroup
+ */
+
+static HLOCAL GRPFILE_ScanGroup(LPCSTR buffer, INT size,
+ LPCSTR lpszGrpFile,
+ BOOL bModifiedFileName)
+{
+ HLOCAL hGroup;
+ INT i, seqnum;
+ LPCSTR extension;
+ LPCSTR lpszName;
+ INT x, y, width, height, iconx, icony, nCmdShow;
+ INT number_of_programs;
+ BOOL bOverwriteFileOk;
+
+ if (buffer[0] != 'P' || buffer[1] != 'M') return(0);
+ if (buffer[2] == 'C' && buffer[3] == 'C')
+ /* original with checksum */
+ bOverwriteFileOk = FALSE;
+ else if (buffer[2] == 'X' && buffer[3] == 'X')
+ /* modified without checksum */
+ bOverwriteFileOk = TRUE;
+ else return(0);
+
+ /* checksum = GET_USHORT(buffer, 4) (ignored) */
+
+ extension = buffer + GET_USHORT(buffer, 6);
+ if (extension == buffer + size) extension = 0;
+ else if (extension + 6 > buffer + size) return(0);
+
+ nCmdShow = GET_USHORT(buffer, 8);
+ x = GET_SHORT(buffer, 10);
+ y = GET_SHORT(buffer, 12);
+ width = GET_USHORT(buffer, 14);
+ height = GET_USHORT(buffer, 16);
+ iconx = GET_SHORT(buffer, 18);
+ icony = GET_SHORT(buffer, 20);
+ lpszName = buffer + GET_USHORT(buffer, 22);
+ if (lpszName >= buffer + size) return(0);
+
+ /* unknown bytes 24 - 31 ignored */
+
+ hGroup = GROUP_AddGroup(lpszName, lpszGrpFile, nCmdShow, x, y,
+ width, height, iconx, icony,
+ bModifiedFileName, bOverwriteFileOk,
+ TRUE);
+ if (!hGroup) return(0);
+
+ number_of_programs = GET_USHORT(buffer, 32);
+ if (2 * number_of_programs + 34 > size) return(0);
+ for (i=0, seqnum=0; i < number_of_programs; i++, seqnum++)
+ {
+ LPCSTR program_ptr = buffer + GET_USHORT(buffer, 34 + 2*i);
+ if (program_ptr + 24 > buffer + size) return(0);
+ if (!GET_USHORT(buffer, 34 + 2*i)) continue;
+ if (!GRPFILE_ScanProgram(buffer, size, program_ptr, seqnum,
+ extension, hGroup, lpszGrpFile))
+ {
+ GROUP_DeleteGroup(hGroup);
+ return(0);
+ }
+ }
+
+ /* FIXME shouldn't be necessary */
+ GROUP_ShowGroupWindow(hGroup);
+
+ return hGroup;
+}
+
+/***********************************************************************
+ * GRPFILE_ScanProgram
+ */
+
+static HLOCAL GRPFILE_ScanProgram(LPCSTR buffer, INT size,
+ LPCSTR program_ptr, INT seqnum,
+ LPCSTR extension, HLOCAL hGroup,
+ LPCSTR lpszGrpFile)
+{
+ INT icontype;
+ HICON hIcon;
+ LPCSTR lpszName, lpszCmdLine, lpszIconFile, lpszWorkDir;
+ LPCSTR iconinfo_ptr, iconANDbits_ptr, iconXORbits_ptr;
+ INT x, y, nIconIndex, iconANDsize, iconXORsize;
+ INT nHotKey, nCmdShow;
+ CURSORICONINFO iconinfo;
+
+ x = GET_SHORT(program_ptr, 0);
+ y = GET_SHORT(program_ptr, 2);
+ nIconIndex = GET_USHORT(program_ptr, 4);
+
+ /* FIXME is this correct ?? */
+ icontype = GET_USHORT(program_ptr, 6);
+ switch (icontype)
+ {
+ default:
+ MessageBox(Globals.hMainWnd, STRING_UNKNOWN_FEATURE_IN_GRPFILE,
+ lpszGrpFile, MB_OK);
+ case 0x048c:
+ iconXORsize = GET_USHORT(program_ptr, 8);
+ iconANDsize = GET_USHORT(program_ptr, 10) / 8;
+ iconinfo_ptr = buffer + GET_USHORT(program_ptr, 12);
+ iconXORbits_ptr = buffer + GET_USHORT(program_ptr, 14);
+ iconANDbits_ptr = buffer + GET_USHORT(program_ptr, 16);
+ iconinfo.ptHotSpot.x = GET_USHORT(iconinfo_ptr, 0);
+ iconinfo.ptHotSpot.y = GET_USHORT(iconinfo_ptr, 2);
+ iconinfo.nWidth = GET_USHORT(iconinfo_ptr, 4);
+ iconinfo.nHeight = GET_USHORT(iconinfo_ptr, 6);
+ iconinfo.nWidthBytes = GET_USHORT(iconinfo_ptr, 8);
+ iconinfo.bPlanes = GET_USHORT(iconinfo_ptr, 10);
+ iconinfo.bBitsPerPixel = GET_USHORT(iconinfo_ptr, 11);
+ break;
+ case 0x000c:
+ iconANDsize = GET_USHORT(program_ptr, 8);
+ iconXORsize = GET_USHORT(program_ptr, 10);
+ iconinfo_ptr = buffer + GET_USHORT(program_ptr, 12);
+ iconANDbits_ptr = buffer + GET_USHORT(program_ptr, 14);
+ iconXORbits_ptr = buffer + GET_USHORT(program_ptr, 16);
+ iconinfo.ptHotSpot.x = GET_USHORT(iconinfo_ptr, 0);
+ iconinfo.ptHotSpot.y = GET_USHORT(iconinfo_ptr, 2);
+ iconinfo.nWidth = GET_USHORT(iconinfo_ptr, 4);
+ iconinfo.nHeight = GET_USHORT(iconinfo_ptr, 6);
+ iconinfo.nWidthBytes = GET_USHORT(iconinfo_ptr, 8) * 8;
+ iconinfo.bPlanes = GET_USHORT(iconinfo_ptr, 10);
+ iconinfo.bBitsPerPixel = GET_USHORT(iconinfo_ptr, 11);
+ }
+
+ if (iconANDbits_ptr + iconANDsize > buffer + size ||
+ iconXORbits_ptr + iconXORsize > buffer + size) return(0);
+
+ hIcon = CreateCursorIconIndirect(Globals.hInstance, &iconinfo,
+ (LPSTR)iconANDbits_ptr,
+ (LPSTR)iconXORbits_ptr);
+
+ lpszName = buffer + GET_USHORT(program_ptr, 18);
+ lpszCmdLine = buffer + GET_USHORT(program_ptr, 20);
+ lpszIconFile = buffer + GET_USHORT(program_ptr, 22);
+ if (iconinfo_ptr + 6 > buffer + size ||
+ lpszName > buffer + size ||
+ lpszCmdLine > buffer + size ||
+ lpszIconFile > buffer + size) return(0);
+
+ /* Scan Extensions */
+ lpszWorkDir = "";
+ nHotKey = 0;
+ nCmdShow = SW_SHOWNORMAL;
+ if (extension)
+ {
+ LPCSTR ptr = extension;
+ while (ptr + 6 <= buffer + size)
+ {
+ UINT type = GET_USHORT(ptr, 0);
+ UINT number = GET_USHORT(ptr, 2);
+ UINT skip = GET_USHORT(ptr, 4);
+
+ if (number == seqnum)
+ {
+ switch (type)
+ {
+ case 0x8000:
+ if (ptr + 10 > buffer + size) return(0);
+ if (ptr[6] != 'P' || ptr[7] != 'M' ||
+ ptr[8] != 'C' || ptr[9] != 'C') return(0);
+ break;
+ case 0x8101:
+ lpszWorkDir = ptr + 6;
+ break;
+ case 0x8102:
+ if (ptr + 8 > buffer + size) return(0);
+ nHotKey = GET_USHORT(ptr, 6);
+ break;
+ case 0x8103:
+ if (ptr + 8 > buffer + size) return(0);
+ nCmdShow = GET_USHORT(ptr, 6);
+ break;
+ default:
+ MessageBox(Globals.hMainWnd,
+ STRING_UNKNOWN_FEATURE_IN_GRPFILE,
+ lpszGrpFile, MB_OK);
+ }
+ }
+ if (!skip) break;
+ ptr += skip;
+ }
+ }
+
+ return (PROGRAM_AddProgram(hGroup, hIcon, lpszName, x, y,
+ lpszCmdLine, lpszIconFile,
+ nIconIndex, lpszWorkDir,
+ nHotKey, nCmdShow));
+}
+
+/***********************************************************************
+ *
+ * GRPFILE_WriteGroupFile
+ */
+
+BOOL GRPFILE_WriteGroupFile(HLOCAL hGroup)
+{
+ CHAR szPath[MAX_PATHNAME_LEN];
+ GROUP *group = LocalLock(hGroup);
+ OFSTRUCT dummy;
+ HFILE file;
+ BOOL ret;
+
+ GRPFILE_ModifyFileName(szPath, LocalLock(group->hGrpFile),
+ MAX_PATHNAME_LEN,
+ group->bFileNameModified);
+
+ /* Try not to overwrite original files */
+
+ /* group->bOverwriteFileOk == TRUE only if a file has the modified format */
+ if (!group->bOverwriteFileOk &&
+ OpenFile(szPath, &dummy, OF_EXIST) != HFILE_ERROR)
+ {
+ CHAR msg[MAX_PATHNAME_LEN + 1000];
+
+ /* Original file exists, try `.gr' extension */
+ GRPFILE_ModifyFileName(szPath, LocalLock(group->hGrpFile),
+ MAX_PATHNAME_LEN, TRUE);
+ if (OpenFile(szPath, &dummy, OF_EXIST) != HFILE_ERROR)
+ {
+ /* File exists. Do not overwrite */
+ if (sizeof(msg) <= lstrlen(STRING_FILE_NOT_OVERWRITTEN_s) + lstrlen(szPath))
+ return FALSE;
+ wsprintf(msg, (LPSTR)STRING_FILE_NOT_OVERWRITTEN_s, szPath);
+ MessageBox(Globals.hMainWnd, msg, STRING_ERROR, MB_OK);
+ return FALSE;
+ }
+ /* Inform about the modified file name */
+ if (sizeof(msg) <= lstrlen(STRING_SAVE_GROUP_AS_s) + lstrlen(szPath))
+ return FALSE;
+ wsprintf(msg, (LPSTR)STRING_SAVE_GROUP_AS_s, szPath);
+ if (IDCANCEL == MessageBox(Globals.hMainWnd, msg, STRING_INFO,
+ MB_OKCANCEL | MB_ICONINFORMATION))
+ return FALSE;
+ }
+
+ {
+ /* Warn about the incompatibility */
+ CHAR msg[MAX_PATHNAME_LEN + 200];
+ wsprintf(msg,
+ "Group files written by this DRAFT Program Manager "
+ "cannot be read by the Microsoft Program Manager!!\n"
+ "Are you sure to write %s?", szPath);
+ if (IDOK != MessageBox(Globals.hMainWnd, msg, "WARNING",
+ MB_OKCANCEL | MB_DEFBUTTON2)) return FALSE;
+ }
+
+ /* FIXME */
+ if (OpenFile(szPath, &dummy, OF_EXIST) == HFILE_ERROR)
+ {
+ CHAR msg[MAX_PATHNAME_LEN + 200];
+ wsprintf(msg, "Cause of a bug you must now touch the file %s\n", szPath);
+ MessageBox(Globals.hMainWnd, msg, "", MB_OK);
+ }
+
+ /* Open file */
+ file = _lopen(szPath, OF_WRITE);
+ if (file != HFILE_ERROR)
+ {
+ ret = GRPFILE_DoWriteGroupFile(file, group);
+ _lclose(file);
+ }
+ else ret = FALSE;
+
+ if (!ret) MAIN_FileWriteError(szPath);
+
+ return(ret);
+}
+
+/***********************************************************************
+ *
+ * GRPFILE_CalculateSizes
+ */
+
+static VOID GRPFILE_CalculateSizes(PROGRAM *program,
+ INT *Progs, INT *Icons)
+{
+ CURSORICONINFO *iconinfo = LocalLock(program->hIcon);
+ INT sizeXor = iconinfo->nHeight * iconinfo->nWidthBytes;
+ INT sizeAnd = iconinfo->nHeight * ((iconinfo->nWidth + 15) / 16 * 2);
+
+ *Progs += 24;
+ *Progs += lstrlen(LocalLock(program->hName)) + 1;
+ *Progs += lstrlen(LocalLock(program->hCmdLine)) + 1;
+ *Progs += lstrlen(LocalLock(program->hIconFile)) + 1;
+
+ *Icons += 12; /* IconInfo */
+ *Icons += sizeAnd;
+ *Icons += sizeXor;
+}
+
+/***********************************************************************
+ *
+ * GRPFILE_DoWriteGroupFile
+ */
+
+static BOOL GRPFILE_DoWriteGroupFile(HFILE file, GROUP *group)
+{
+ BYTE buffer[34];
+ HLOCAL hProgram;
+ INT NumProg, Title, Progs, Icons, Extension;
+ INT CurrProg, CurrIcon, nCmdShow, ptr, seqnum;
+ BOOL need_extension;
+ LPCSTR lpszTitle = LocalLock(group->hName);
+
+ /* Calculate offsets */
+ NumProg = 0;
+ Icons = 0;
+ Extension = 0;
+ need_extension = FALSE;
+ hProgram = group->hPrograms;
+ while(hProgram)
+ {
+ PROGRAM *program = LocalLock(hProgram);
+ LPCSTR lpszWorkDir = LocalLock(program->hWorkDir);
+
+ NumProg++;
+ GRPFILE_CalculateSizes(program, &Icons, &Extension);
+
+ /* Set a flag if an extension is needed */
+ if (lpszWorkDir[0] || program->nHotKey ||
+ program->nCmdShow != SW_SHOWNORMAL) need_extension = TRUE;
+
+ hProgram = program->hNext;
+ }
+ Title = 34 + NumProg * 2;
+ Progs = Title + lstrlen(lpszTitle) + 1;
+ Icons += Progs;
+ Extension += Icons;
+
+ /* Header */
+ buffer[0] = 'P';
+ buffer[1] = 'M';
+#if 0
+ buffer[2] = 'C'; /* Original magic number */
+ buffer[3] = 'C';
+#else
+ buffer[2] = 'X'; /* Modified magic number: no checksum */
+ buffer[3] = 'X';
+#endif
+ PUT_SHORT(buffer, 4, 0); /* Checksum ignored */
+ PUT_SHORT(buffer, 6, Extension);
+ /* Update group->nCmdShow */
+ if (IsIconic(group->hWnd)) nCmdShow = SW_SHOWMINIMIZED;
+ else if (IsZoomed(group->hWnd)) nCmdShow = SW_SHOWMAXIMIZED;
+ else nCmdShow = SW_SHOWNORMAL;
+ PUT_SHORT(buffer, 8, nCmdShow);
+ PUT_SHORT(buffer, 10, group->x);
+ PUT_SHORT(buffer, 12, group->y);
+ PUT_SHORT(buffer, 14, group->width);
+ PUT_SHORT(buffer, 16, group->height);
+ PUT_SHORT(buffer, 18, group->iconx);
+ PUT_SHORT(buffer, 20, group->icony);
+ PUT_SHORT(buffer, 22, Title);
+ PUT_SHORT(buffer, 24, 0x0020); /* unknown */
+ PUT_SHORT(buffer, 26, 0x0020); /* unknown */
+ PUT_SHORT(buffer, 28, 0x0108); /* unknown */
+ PUT_SHORT(buffer, 30, 0x0000); /* unknown */
+ PUT_SHORT(buffer, 32, NumProg);
+
+ if (HFILE_ERROR == _lwrite(file, buffer, 34)) return FALSE;
+
+ /* Program table */
+ CurrProg = Progs;
+ CurrIcon = Icons;
+ hProgram = group->hPrograms;
+ while(hProgram)
+ {
+ PROGRAM *program = LocalLock(hProgram);
+
+ PUT_SHORT(buffer, 0, CurrProg);
+ if (HFILE_ERROR == _lwrite(file, buffer, 2)) return FALSE;
+
+ GRPFILE_CalculateSizes(program, &CurrProg, &CurrIcon);
+ hProgram = program->hNext;
+ }
+
+ /* Title */
+ if (HFILE_ERROR == _lwrite(file, lpszTitle, lstrlen(lpszTitle) + 1))
+ return FALSE;
+
+ /* Program entries */
+ CurrProg = Progs;
+ CurrIcon = Icons;
+ hProgram = group->hPrograms;
+ while(hProgram)
+ {
+ PROGRAM *program = LocalLock(hProgram);
+ CURSORICONINFO *iconinfo = LocalLock(program->hIcon);
+ LPCSTR Name = LocalLock(program->hName);
+ LPCSTR CmdLine = LocalLock(program->hCmdLine);
+ LPCSTR IconFile = LocalLock(program->hIconFile);
+ INT sizeXor = iconinfo->nHeight * iconinfo->nWidthBytes;
+ INT sizeAnd = iconinfo->nHeight * ((iconinfo->nWidth + 15) / 16 * 2);
+
+ PUT_SHORT(buffer, 0, program->x);
+ PUT_SHORT(buffer, 2, program->y);
+ PUT_SHORT(buffer, 4, program->nIconIndex);
+ PUT_SHORT(buffer, 6, 0x048c); /* unknown */
+ PUT_SHORT(buffer, 8, sizeXor);
+ PUT_SHORT(buffer, 10, sizeAnd * 8);
+ PUT_SHORT(buffer, 12, CurrIcon);
+ PUT_SHORT(buffer, 14, CurrIcon + 12 + sizeAnd);
+ PUT_SHORT(buffer, 16, CurrIcon + 12);
+ ptr = CurrProg + 24;
+ PUT_SHORT(buffer, 18, ptr);
+ ptr += lstrlen(Name) + 1;
+ PUT_SHORT(buffer, 20, ptr);
+ ptr += lstrlen(CmdLine) + 1;
+ PUT_SHORT(buffer, 22, ptr);
+
+ if (HFILE_ERROR == _lwrite(file, buffer, 24) ||
+ HFILE_ERROR == _lwrite(file, Name, lstrlen(Name) + 1) ||
+ HFILE_ERROR == _lwrite(file, CmdLine, lstrlen(CmdLine) + 1) ||
+ HFILE_ERROR == _lwrite(file, IconFile, lstrlen(IconFile) + 1))
+ return FALSE;
+
+ GRPFILE_CalculateSizes(program, &CurrProg, &CurrIcon);
+ hProgram = program->hNext;
+ }
+
+ /* Icons */
+ hProgram = group->hPrograms;
+ while(hProgram)
+ {
+ PROGRAM *program = LocalLock(hProgram);
+ CURSORICONINFO *iconinfo = LocalLock(program->hIcon);
+ SEGPTR XorBits, AndBits;
+ INT sizeXor = iconinfo->nHeight * iconinfo->nWidthBytes;
+ INT sizeAnd = iconinfo->nHeight * ((iconinfo->nWidth + 15) / 16 * 2);
+ DumpIcon(LocalLock(program->hIcon), 0, &XorBits, &AndBits);
+
+ PUT_SHORT(buffer, 0, iconinfo->ptHotSpot.x);
+ PUT_SHORT(buffer, 2, iconinfo->ptHotSpot.y);
+ PUT_SHORT(buffer, 4, iconinfo->nWidth);
+ PUT_SHORT(buffer, 6, iconinfo->nHeight);
+ PUT_SHORT(buffer, 8, iconinfo->nWidthBytes);
+ buffer[10] = iconinfo->bPlanes;
+ buffer[11] = iconinfo->bBitsPerPixel;
+
+ if (HFILE_ERROR == _lwrite(file, buffer, 12) ||
+ HFILE_ERROR == _lwrite(file, AndBits, sizeAnd) ||
+ HFILE_ERROR == _lwrite(file, XorBits, sizeXor)) return FALSE;
+
+ hProgram = program->hNext;
+ }
+
+ if (need_extension)
+ {
+ /* write `PMCC' extension */
+ PUT_SHORT(buffer, 0, 0x8000);
+ PUT_SHORT(buffer, 2, 0xffff);
+ PUT_SHORT(buffer, 4, 0x000a);
+ buffer[6] = 'P', buffer[7] = 'M';
+ buffer[8] = 'C', buffer[9] = 'C';
+ if (HFILE_ERROR == _lwrite(file, buffer, 10)) return FALSE;
+
+ seqnum = 0;
+ hProgram = group->hPrograms;
+ while(hProgram)
+ {
+ PROGRAM *program = LocalLock(hProgram);
+ LPCSTR lpszWorkDir = LocalLock(program->hWorkDir);
+
+ /* Working directory */
+ if (lpszWorkDir[0])
+ {
+ PUT_SHORT(buffer, 0, 0x8101);
+ PUT_SHORT(buffer, 2, seqnum);
+ PUT_SHORT(buffer, 4, 7 + lstrlen(lpszWorkDir));
+ if (HFILE_ERROR == _lwrite(file, buffer, 6) ||
+ HFILE_ERROR == _lwrite(file, lpszWorkDir, lstrlen(lpszWorkDir) + 1))
+ return FALSE;
+ }
+
+ /* Hot key */
+ if (program->nHotKey)
+ {
+ PUT_SHORT(buffer, 0, 0x8102);
+ PUT_SHORT(buffer, 2, seqnum);
+ PUT_SHORT(buffer, 4, 8);
+ PUT_SHORT(buffer, 6, program->nHotKey);
+ if (HFILE_ERROR == _lwrite(file, buffer, 8)) return FALSE;
+ }
+
+ /* Show command */
+ if (program->nCmdShow)
+ {
+ PUT_SHORT(buffer, 0, 0x8103);
+ PUT_SHORT(buffer, 2, seqnum);
+ PUT_SHORT(buffer, 4, 8);
+ PUT_SHORT(buffer, 6, program->nCmdShow);
+ if (HFILE_ERROR == _lwrite(file, buffer, 8)) return FALSE;
+ }
+
+ seqnum++;
+ hProgram = program->hNext;
+ }
+
+ /* Write `End' extension */
+ PUT_SHORT(buffer, 0, 0xffff);
+ PUT_SHORT(buffer, 2, 0xffff);
+ PUT_SHORT(buffer, 4, 0x0000);
+ if (HFILE_ERROR == _lwrite(file, buffer, 6)) return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Local Variables: */
+/* c-file-style: "GNU" */
+/* End: */
diff --git a/programs/progman/license.c b/programs/progman/license.c
new file mode 100644
index 0000000..14308cd
--- /dev/null
+++ b/programs/progman/license.c
@@ -0,0 +1,32 @@
+#include <windows.h>
+#include "license.h"
+
+static LICENSE* SelectLanguage(LPCSTR Language)
+{
+#if 0
+ if (!lstrcmp(Language, "Da")) return(&WineLicense_Cz);
+ if (!lstrcmp(Language, "Da")) return(&WineLicense_Da);
+ if (!lstrcmp(Language, "De")) return(&WineLicense_De);
+ if (!lstrcmp(Language, "Es")) return(&WineLicense_Es);
+ if (!lstrcmp(Language, "Fi")) return(&WineLicense_Fi);
+ if (!lstrcmp(Language, "Fr")) return(&WineLicense_Fr);
+ if (!lstrcmp(Language, "No")) return(&WineLicense_No);
+#endif
+ return(&WineLicense_En);
+}
+
+VOID WineLicense(HWND Wnd, LPCSTR Language)
+{
+ LICENSE *License = SelectLanguage(Language);
+
+ MessageBox(Wnd, License->License, License->LicenseCaption,
+ MB_ICONINFORMATION | MB_OK);
+}
+
+VOID WineWarranty(HWND Wnd, LPCSTR Language)
+{
+ LICENSE *License = SelectLanguage(Language);
+
+ MessageBox(Wnd, License->Warranty, License->WarrantyCaption,
+ MB_ICONEXCLAMATION | MB_OK);
+}
diff --git a/programs/progman/license.h b/programs/progman/license.h
new file mode 100644
index 0000000..97fa9ba
--- /dev/null
+++ b/programs/progman/license.h
@@ -0,0 +1,11 @@
+VOID WineLicense(HWND hWnd, LPCSTR lpszLanguage);
+VOID WineWarranty(HWND hWnd, LPCSTR language);
+
+typedef struct
+{
+ LPCSTR License, LicenseCaption;
+ LPCSTR Warranty, WarrantyCaption;
+} LICENSE;
+
+extern LICENSE WineLicense_Cz, WineLicense_Da, WineLicense_De, WineLicense_En;
+extern LICENSE WineLicense_Es, WineLicense_Fi, WineLicense_Fr, WineLicense_No;
diff --git a/programs/progman/main.c b/programs/progman/main.c
new file mode 100644
index 0000000..f6173e2
--- /dev/null
+++ b/programs/progman/main.c
@@ -0,0 +1,553 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid <uschmid@mail.hh.provi.de>
+ */
+
+#include <stdio.h>
+#include <windows.h>
+#include "license.h"
+#include "progman.h"
+#ifdef WINELIB
+#include <options.h>
+#include <shell.h>
+#endif
+
+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 (HANDLE hInstance, HANDLE prev, LPSTR cmdline, int show)
+{
+ MSG msg;
+
+#ifndef WINELIB
+ Globals.lpszIniFile = "progman.ini";
+ Globals.lpszIcoFile = "progman.ico";
+#else /* Configuration in `wine.ini' */
+ {
+ CHAR buffer[MAX_PATHNAME_LEN], *p;
+
+ /* Redirect `progman.ini' */
+ PROFILE_GetWineIniString("progman", "progman.ini", "progman.ini",
+ buffer, sizeof(buffer));
+ Globals.lpszIniFile = p = LocalLock(LocalAlloc(LMEM_FIXED, lstrlen(buffer)));
+ hmemcpy(p, buffer, 1 + lstrlen(buffer));
+
+ /* Redirect `progman.ico' */
+ PROFILE_GetWineIniString("progman", "progman.ico", "progman.ico",
+ buffer, sizeof(buffer));
+ Globals.lpszIcoFile = p = LocalLock(LocalAlloc(LMEM_FIXED, lstrlen(buffer)));
+ hmemcpy(p, buffer, 1 + lstrlen(buffer));
+ }
+#endif
+
+ /* Select Language */
+ Globals.lpszLanguage = "En";
+#ifdef WINELIB
+ if (Options.language == LANG_Cz) Globals.lpszLanguage = "Cz";
+ if (Options.language == LANG_Da) Globals.lpszLanguage = "Da";
+ if (Options.language == LANG_De) Globals.lpszLanguage = "De";
+ if (Options.language == LANG_Es) Globals.lpszLanguage = "Es";
+ if (Options.language == LANG_Fi) Globals.lpszLanguage = "Fi";
+ if (Options.language == LANG_Fr) Globals.lpszLanguage = "Fr";
+ if (Options.language == LANG_No) Globals.lpszLanguage = "No";
+#ifndef HAVE_WINE_CONSTRUCTOR
+ /* Register resources */
+ LIBWINE_Register_accel();
+ LIBWINE_Register_De();
+ LIBWINE_Register_En();
+#endif
+#endif
+
+ Globals.hInstance = hInstance;
+ Globals.hGroups = 0;
+
+ /* FIXME should use MDI */
+ Globals.hActiveGroup = 0;
+
+ /* Read Options from `progman.ini' */
+ Globals.bAutoArrange =
+ GetPrivateProfileInt("Settings", "AutoArrange", 0, Globals.lpszIniFile);
+ Globals.bMinOnRun =
+ GetPrivateProfileInt("Settings", "MinOnRun", 0, Globals.lpszIniFile);
+ Globals.bSaveSettings =
+ GetPrivateProfileInt("Settings", "SaveSettings", 0, Globals.lpszIniFile);
+
+ /* Load default icons */
+ Globals.hMainIcon = ExtractIcon(Globals.hInstance, Globals.lpszIcoFile, 0);
+ Globals.hGroupIcon = ExtractIcon(Globals.hInstance, Globals.lpszIcoFile, 0);
+ Globals.hDefaultIcon = ExtractIcon(Globals.hInstance, Globals.lpszIcoFile, 0);
+ if (!Globals.hMainIcon) Globals.hMainIcon = LoadIcon(0, MAKEINTRESOURCE(DEFAULTICON));
+ if (!Globals.hGroupIcon) Globals.hGroupIcon = LoadIcon(0, MAKEINTRESOURCE(DEFAULTICON));
+ if (!Globals.hDefaultIcon) Globals.hDefaultIcon = LoadIcon(0, MAKEINTRESOURCE(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 = LoadAccelerators(Globals.hInstance, STRING_ACCEL);
+
+ /* Setup menu, stringtable and resourcenames */
+ STRING_SelectLanguage(Globals.lpszLanguage);
+
+ MAIN_CreateMDIWindow();
+
+ /* Initialize groups */
+ MAIN_CreateGroups();
+
+ /* Start initial applications */
+ MAIN_AutoStart();
+
+ /* Message loop */
+ while (GetMessage (&msg, 0, 0, 0))
+ if (!TranslateAccelerator(Globals.hMainWnd, Globals.hAccel, &msg))
+ {
+ TranslateMessage (&msg);
+ DispatchMessage (&msg);
+ }
+ return 0;
+}
+
+/***********************************************************************
+ *
+ * MAIN_CreateGroups
+ */
+
+static VOID MAIN_CreateGroups()
+{
+ CHAR buffer[BUFFER_SIZE];
+ CHAR szPath[MAX_PATHNAME_LEN];
+ CHAR key[20], *ptr;
+
+ /* Initialize groups according the `Order' entry of `progman.ini' */
+ GetPrivateProfileString("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_FileReadError(Globals.lpszIniFile);
+ if (ret != 1) break;
+
+ sprintf(key, "Group%d", num);
+ GetPrivateProfileString("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()
+{
+ CHAR buffer[BUFFER_SIZE];
+ HLOCAL hGroup, hProgram;
+
+ GetPrivateProfileString("Settings", "AutoStart", "Autostart", buffer,
+ sizeof(buffer), Globals.lpszIniFile);
+
+ for (hGroup = GROUP_FirstGroup(); hGroup; hGroup = GROUP_NextGroup(hGroup))
+ if (!lstrcmp(buffer, GROUP_GroupName(hGroup)))
+ for (hProgram = PROGRAM_FirstProgram(hGroup); hProgram;
+ hProgram = PROGRAM_NextProgram(hProgram))
+ PROGRAM_ExecuteProgram(hProgram);
+}
+
+/***********************************************************************
+ *
+ * MAIN_MainWndProc
+ */
+
+static LRESULT MAIN_MainWndProc (HWND hWnd, UINT msg,
+ WPARAM wParam, LPARAM lParam)
+{
+#if 0
+ printf("M %4.4x %4.4x\n", msg, wParam);
+#endif
+ 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 (wParam < PM_FIRST_CHILD)
+ MAIN_MenuCommand(hWnd, wParam, lParam);
+ break;
+
+ case WM_DESTROY:
+ PostQuitMessage (0);
+ break;
+ }
+ return(DefFrameProc(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(STRING_DELETE_PROGRAM_s, PROGRAM_ProgramName(hActiveProgram)))
+ PROGRAM_DeleteProgram(hActiveProgram, TRUE);
+ }
+ else if (hActiveGroup)
+ {
+ if (DIALOG_Delete(STRING_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));
+ WritePrivateProfileString("Settings", "AutoArrange",
+ Globals.bAutoArrange ? "1" : "0",
+ Globals.lpszIniFile);
+ WriteOutProfiles();
+ 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));
+ WritePrivateProfileString("Settings", "MinOnRun",
+ Globals.bMinOnRun ? "1" : "0",
+ Globals.lpszIniFile);
+ WriteOutProfiles();
+ break;
+
+ case PM_SAVE_SETTINGS:
+ Globals.bSaveSettings = !Globals.bSaveSettings;
+ CheckMenuItem(Globals.hOptionMenu, PM_SAVE_SETTINGS,
+ MF_BYCOMMAND | (Globals.bSaveSettings ?
+ MF_CHECKED : MF_UNCHECKED));
+ WritePrivateProfileString("Settings", "SaveSettings",
+ Globals.bSaveSettings ? "1" : "0",
+ Globals.lpszIniFile);
+ WriteOutProfiles();
+ break;
+
+ /* Menu Windows */
+ case PM_ARRANGE:
+ SendMessage(Globals.hMDIWnd, WM_MDIICONARRANGE, 0, 0);
+ break;
+
+ /* Menu Language */
+ case PM_Da: STRING_SelectLanguage("Da"); break;
+ case PM_De: STRING_SelectLanguage("De"); break;
+ case PM_En: STRING_SelectLanguage("En"); break;
+ case PM_Es: STRING_SelectLanguage("Es"); break;
+ case PM_Fi: STRING_SelectLanguage("Fi"); break;
+ case PM_Fr: STRING_SelectLanguage("Fr"); break;
+ case PM_No: STRING_SelectLanguage("No"); break;
+
+ /* Menu Help */
+ case PM_CONTENTS:
+ if (!WinHelp(Globals.hMainWnd, "progman.hlp", HELP_INDEX, 0))
+ MAIN_WinHelpError();
+ break;
+
+ case PM_HELPONHELP:
+ if (!WinHelp(Globals.hMainWnd, "progman.hlp", HELP_HELPONHELP, 0))
+ MAIN_WinHelpError();
+ break;
+
+ case PM_TUTORIAL:
+ WinExec("wintutor.exe", SW_SHOWNORMAL);
+ break;
+
+ case PM_LICENSE:
+ WineLicense(Globals.hMainWnd, Globals.lpszLanguage);
+ break;
+
+ case PM_NO_WARRANTY:
+ WineWarranty(Globals.hMainWnd, Globals.lpszLanguage);
+ break;
+
+#ifdef WINELIB
+ case PM_ABOUT_WINE:
+ {
+ extern const char people[];
+ ShellAbout(hWnd, "WINE", people, 0);
+ }
+ break;
+#endif
+
+ default:
+ MAIN_NotImplementedError();
+ break;
+ }
+}
+
+/***********************************************************************
+ *
+ * MAIN_RegisterMainWinClass
+ */
+
+static ATOM MAIN_RegisterMainWinClass()
+{
+ WNDCLASS 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 = LoadCursor (0, IDC_ARROW);
+ class.hbrBackground = GetStockObject (NULL_BRUSH);
+ class.lpszMenuName = 0;
+ class.lpszClassName = STRING_MAIN_WIN_CLASS_NAME;
+
+ return RegisterClass(&class);
+}
+
+/***********************************************************************
+ *
+ * MAIN_CreateMainWindow
+ */
+
+static VOID MAIN_CreateMainWindow()
+{
+ INT left , top, right, bottom, width, height, show;
+ CHAR buffer[100];
+
+ Globals.hMDIWnd = 0;
+ Globals.hMainMenu = 0;
+
+ /* Get the geometry of the main window */
+ GetPrivateProfileString("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 =
+ CreateWindow (STRING_MAIN_WIN_CLASS_NAME, "",
+ WS_OVERLAPPEDWINDOW, left, top, width, height,
+ 0, 0, Globals.hInstance, 0);
+
+ ShowWindow (Globals.hMainWnd, show);
+ UpdateWindow (Globals.hMainWnd);
+}
+
+/***********************************************************************
+ *
+ * MAIN_CreateMDIWindow
+ */
+
+static VOID MAIN_CreateMDIWindow()
+{
+ 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 =
+ CreateWindow (STRING_MDI_WIN_CLASS_NAME, "",
+ 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_ReplaceString
+ */
+
+VOID MAIN_ReplaceString(HLOCAL *handle, LPSTR replace)
+{
+ HLOCAL newhandle = LocalAlloc(LMEM_FIXED, strlen(replace) + 1);
+ if (newhandle)
+ {
+ LPSTR newstring = LocalLock(newhandle);
+ lstrcpy(newstring, replace);
+ LocalFree(*handle);
+ *handle = newhandle;
+ }
+ else MAIN_OutOfMemoryError();
+}
+
+/***********************************************************************
+ *
+ * MAIN_NotImplementedError
+ */
+
+VOID MAIN_NotImplementedError()
+{
+ MessageBox(Globals.hMainWnd,
+ STRING_NOT_IMPLEMENTED, STRING_ERROR, MB_OK);
+}
+
+/***********************************************************************
+ *
+ * MAIN_OutOfMemoryError
+ */
+
+VOID MAIN_OutOfMemoryError()
+{
+ MessageBox(Globals.hMainWnd,
+ STRING_OUT_OF_MEMORY, STRING_ERROR, MB_OK);
+}
+
+/***********************************************************************
+ *
+ * MAIN_WinHelpError
+ */
+
+VOID MAIN_WinHelpError()
+{
+ MessageBox(Globals.hMainWnd,
+ STRING_WINHELP_ERROR, STRING_ERROR, MB_OK);
+}
+
+/***********************************************************************
+ *
+ * MAIN_FileReadError
+ */
+
+VOID MAIN_FileReadError(LPCSTR lpszPath)
+{
+ CHAR msg[MAX_PATHNAME_LEN + 1000];
+ if (sizeof(msg) <= strlen(STRING_FILE_READ_ERROR_s) + strlen(lpszPath)) return;
+ wsprintf(msg, (LPSTR)STRING_FILE_READ_ERROR_s, lpszPath);
+ MessageBox(Globals.hMainWnd, msg, STRING_ERROR, MB_OK);
+}
+
+/***********************************************************************
+ *
+ * MAIN_FileWriteError
+ */
+
+VOID MAIN_FileWriteError(LPCSTR lpszPath)
+{
+ CHAR msg[MAX_PATHNAME_LEN + 1000];
+ if (sizeof(msg) <= strlen(STRING_FILE_WRITE_ERROR_s) + strlen(lpszPath)) return;
+ wsprintf(msg, (LPSTR)STRING_FILE_WRITE_ERROR_s, lpszPath);
+ MessageBox(Globals.hMainWnd, msg, STRING_ERROR, MB_OK);
+}
+
+/***********************************************************************
+ *
+ * MAIN_GrpFileReadError
+ */
+
+VOID MAIN_GrpFileReadError(LPCSTR lpszPath)
+{
+ CHAR msg[MAX_PATHNAME_LEN + 1000];
+ if (sizeof(msg) <= strlen(STRING_GRPFILE_READ_ERROR_s) + strlen(lpszPath)) return;
+ wsprintf(msg, (LPSTR)STRING_GRPFILE_READ_ERROR_s, lpszPath);
+ MessageBox(Globals.hMainWnd, msg, STRING_ERROR, MB_YESNO);
+}
+
+/* Local Variables: */
+/* c-file-style: "GNU" */
+/* End: */
diff --git a/programs/progman/progman.h b/programs/progman/progman.h
new file mode 100644
index 0000000..5d72ed9
--- /dev/null
+++ b/programs/progman/progman.h
@@ -0,0 +1,347 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid
+ */
+
+#ifndef PROGMAN_H
+#define PROGMAN_H
+
+#ifndef RC_INVOKED
+
+#include "windows.h"
+
+/* FIXME should use WinExec from -lwine */
+#ifdef WINELIB
+#define WinExec ProgmanWinExec
+#define WinHelp ProgmanWinHelp
+HANDLE ProgmanWinExec(LPSTR,WORD);
+BOOL ProgmanWinHelp(HWND,LPSTR,WORD,DWORD);
+#endif
+
+#define MAX_PATHNAME_LEN 1024
+
+/* Fallback icon */
+#ifdef WINELIB
+#define DEFAULTICON OIC_WINEICON
+#else
+#define DEFAULTICON OIC_LANDSCAPE
+#endif
+
+/* Icon index in M$ Window's progman.exe */
+#define PROGMAN_ICON_INDEX 0
+#define GROUP_ICON_INDEX 6
+#define DEFAULT_ICON_INDEX 7
+
+#define DEF_GROUP_WIN_XPOS 100
+#define DEF_GROUP_WIN_YPOS 100
+#define DEF_GROUP_WIN_WIDTH 300
+#define DEF_GROUP_WIN_HEIGHT 200
+
+typedef struct
+{
+ HLOCAL hGroup;
+ HLOCAL hPrior;
+ HLOCAL hNext;
+ HWND hWnd;
+ /**/ /* Numbers are byte indexes in *.grp */
+
+ /**/ /* Program entry */
+ INT x, y; /* 0 - 3 */
+ INT nIconIndex; /* 4 - 5 */
+ HICON hIcon;
+ /* icon flags ??? */ /* 6 - 7 */
+ /* iconANDsize */ /* 8 - 9 */
+ /* iconXORsize */ /* 10 - 11 */
+ /* pointer to IconInfo */ /* 12 - 13 */
+ /* pointer to iconXORbits */ /* 14 - 15 */ /* sometimes iconANDbits ?! */
+ /* pointer to iconANDbits */ /* 16 - 17 */ /* sometimes iconXORbits ?! */
+ HLOCAL hName; /* 18 - 19 */
+ HLOCAL hCmdLine; /* 20 - 21 */
+ HLOCAL hIconFile; /* 22 - 23 */
+ HLOCAL hWorkDir; /* Extension 0x8101 */
+ INT nHotKey; /* Extension 0x8102 */
+ /* Modifier: bit 8... */
+ INT nCmdShow; /* Extension 0x8103 */
+
+ /**/ /* IconInfo */
+ /* HotSpot x ??? */ /* 0 - 1 */
+ /* HotSpot y ??? */ /* 2 - 3 */
+ /* Width */ /* 4 - 5 */
+ /* Height */ /* 6 - 7 */
+ /* WidthBytes ??? */ /* 8 - 9 */
+ /* Planes */ /* 10 - 10 */
+ /* BitsPerPixel */ /* 11 - 11 */
+} PROGRAM;
+
+typedef struct
+{
+ HLOCAL hPrior;
+ HLOCAL hNext;
+ HWND hWnd;
+ HLOCAL hGrpFile;
+ HLOCAL hActiveProgram;
+ BOOL bFileNameModified;
+ BOOL bOverwriteFileOk;
+ INT seqnum;
+
+ /**/ /* Absolute */
+ /* magic `PMCC' */ /* 0 - 3 */
+ /* checksum */ /* 4 - 5 */
+ /* Extension ptr */ /* 6 - 7 */
+ INT nCmdShow; /* 8 - 9 */
+ INT x, y; /* 10 - 13 */
+ INT width, height; /* 14 - 17 */
+ INT iconx, icony; /* 18 - 21 */
+ HLOCAL hName; /* 22 - 23 */
+ /* unknown */ /* 24 - 31 */
+ /* number of programs */ /* 32 - 33 */
+ HLOCAL hPrograms; /* 34 ... */
+
+ /**/ /* Extensions */
+ /* Extension type */ /* 0 - 1 */
+ /* Program number */ /* 2 - 3 */
+ /* Size of entry */ /* 4 - 5 */
+ /* Data */ /* 6 ... */
+
+ /* magic `PMCC' */ /* Extension 0x8000 */
+ /* End of Extensions */ /* Extension 0xffff */
+} GROUP;
+
+typedef struct
+{
+ HANDLE hInstance;
+ HANDLE hAccel;
+ HWND hMainWnd;
+ HWND hMDIWnd;
+ HICON hMainIcon;
+ HICON hGroupIcon;
+ HICON hDefaultIcon;
+ HMENU hMainMenu;
+ HMENU hFileMenu;
+ HMENU hOptionMenu;
+ HMENU hWindowsMenu;
+ LPCSTR lpszIniFile;
+ LPCSTR lpszIcoFile;
+ BOOL bAutoArrange;
+ BOOL bSaveSettings;
+ BOOL bMinOnRun;
+ HLOCAL hGroups;
+ LPCSTR lpszLanguage;
+ LPCSTR *StringTable;
+ /* FIXME should use MDI */
+ HLOCAL hActiveGroup;
+} GLOBALS;
+
+extern GLOBALS Globals;
+
+VOID MAIN_ReplaceString(HLOCAL *handle, LPSTR replacestring);
+VOID MAIN_NotImplementedError(void);
+VOID MAIN_FileReadError(LPCSTR lpszPath);
+VOID MAIN_FileWriteError(LPCSTR lpszPath);
+VOID MAIN_GrpFileReadError(LPCSTR lpszPath);
+VOID MAIN_OutOfMemoryError(void);
+VOID MAIN_WinHelpError(void);
+
+HLOCAL GRPFILE_ReadGroupFile(const char* path);
+BOOL GRPFILE_WriteGroupFile(HLOCAL hGroup);
+
+ATOM GROUP_RegisterGroupWinClass(void);
+HLOCAL GROUP_AddGroup(LPCSTR lpszName, LPCSTR lpszGrpFile, INT showcmd,
+ INT x, INT y, INT width, INT heiht,
+ INT iconx, INT icony,
+ BOOL bModifiedFileName, BOOL bOverwriteFileOk,
+ /* FIXME shouldn't be necessary */
+ BOOL bSuppressShowWindow);
+VOID GROUP_NewGroup(void);
+VOID GROUP_ModifyGroup(HLOCAL hGroup);
+VOID GROUP_DeleteGroup(HLOCAL hGroup);
+/* FIXME shouldn't be necessary */
+VOID GROUP_ShowGroupWindow(HLOCAL hGroup);
+HLOCAL GROUP_FirstGroup(void);
+HLOCAL GROUP_NextGroup(HLOCAL hGroup);
+HLOCAL GROUP_ActiveGroup(void);
+HWND GROUP_GroupWnd(HLOCAL hGroup);
+LPCSTR GROUP_GroupName(HLOCAL hGroup);
+
+ATOM PROGRAM_RegisterProgramWinClass(void);
+HLOCAL PROGRAM_AddProgram(HLOCAL hGroup, HICON hIcon, LPCSTR lpszName,
+ INT x, INT y, LPCSTR lpszCmdLine,
+ LPCSTR lpszIconFile, INT nIconIndex,
+ LPCSTR lpszWorkDir, INT nHotKey, INT nCmdShow);
+VOID PROGRAM_NewProgram(HLOCAL hGroup);
+VOID PROGRAM_ModifyProgram(HLOCAL hProgram);
+VOID PROGRAM_CopyMoveProgram(HLOCAL hProgram, BOOL bMove);
+VOID PROGRAM_DeleteProgram(HLOCAL hProgram, BOOL BUpdateGrpFile);
+HLOCAL PROGRAM_FirstProgram(HLOCAL hGroup);
+HLOCAL PROGRAM_NextProgram(HLOCAL hProgram);
+HLOCAL PROGRAM_ActiveProgram(HLOCAL hGroup);
+LPCSTR PROGRAM_ProgramName(HLOCAL hProgram);
+VOID PROGRAM_ExecuteProgram(HLOCAL hLocal);
+
+INT DIALOG_New(INT nDefault);
+HLOCAL DIALOG_CopyMove(LPCSTR lpszProgramName, LPCSTR lpszGroupName, BOOL bMove);
+BOOL DIALOG_Delete(LPCSTR lpszFormat, LPCSTR lpszName);
+BOOL DIALOG_GroupAttributes(LPSTR lpszTitle, LPSTR lpszPath, INT nSize);
+BOOL DIALOG_ProgramAttributes(LPSTR lpszTitle, LPSTR lpszCmdLine,
+ LPSTR lpszWorkDir, LPSTR lpszIconFile,
+ HICON *lphIcon, INT *nIconIndex,
+ INT *lpnHotKey, INT *lpnCmdShow, INT nSize);
+VOID DIALOG_Symbol(HICON *lphIcon, LPSTR lpszIconFile,
+ INT *lpnIconIndex, INT nSize);
+VOID DIALOG_Execute(void);
+
+VOID STRING_SelectLanguage(LPCSTR lang);
+
+/* Class names */
+extern CHAR STRING_MAIN_WIN_CLASS_NAME[];
+extern CHAR STRING_MDI_WIN_CLASS_NAME[];
+extern CHAR STRING_GROUP_WIN_CLASS_NAME[];
+extern CHAR STRING_PROGRAM_WIN_CLASS_NAME[];
+
+/* Resource names */
+extern CHAR STRING_ACCEL[];
+extern CHAR STRING_MAIN_Xx[];
+extern CHAR STRING_NEW_Xx[];
+extern CHAR STRING_OPEN_Xx[];
+extern CHAR STRING_MOVE_Xx[];
+extern CHAR STRING_COPY_Xx[];
+extern CHAR STRING_DELETE_Xx[];
+extern CHAR STRING_GROUP_Xx[];
+extern CHAR STRING_PROGRAM_Xx[];
+extern CHAR STRING_SYMBOL_Xx[];
+extern CHAR STRING_EXECUTE_Xx[];
+
+/* Strings */
+#define STRING_PROGRAM_MANAGER Globals.StringTable[ 0]
+#define STRING_ERROR Globals.StringTable[ 1]
+#define STRING_INFO Globals.StringTable[ 2]
+#define STRING_DELETE Globals.StringTable[ 3]
+#define STRING_DELETE_GROUP_s Globals.StringTable[ 4]
+#define STRING_DELETE_PROGRAM_s Globals.StringTable[ 5]
+#define STRING_NOT_IMPLEMENTED Globals.StringTable[ 6]
+#define STRING_FILE_READ_ERROR_s Globals.StringTable[ 7]
+#define STRING_FILE_WRITE_ERROR_s Globals.StringTable[ 8]
+#define STRING_GRPFILE_READ_ERROR_s Globals.StringTable[ 9]
+#define STRING_OUT_OF_MEMORY Globals.StringTable[10]
+#define STRING_WINHELP_ERROR Globals.StringTable[11]
+#define STRING_UNKNOWN_FEATURE_IN_GRPFILE Globals.StringTable[12]
+#define STRING_FILE_NOT_OVERWRITTEN_s Globals.StringTable[13]
+#define STRING_SAVE_GROUP_AS_s Globals.StringTable[14]
+#define STRING_NO_HOT_KEY Globals.StringTable[15]
+#define STRING_BROWSE_EXE_FILTER Globals.StringTable[16]
+#define STRING_BROWSE_ICO_FILTER Globals.StringTable[17]
+#define NUMBER_OF_STRINGS 18
+
+extern LPCSTR StringTableCz[];
+extern LPCSTR StringTableDa[];
+extern LPCSTR StringTableDe[];
+extern LPCSTR StringTableEn[];
+extern LPCSTR StringTableEs[];
+extern LPCSTR StringTableFi[];
+extern LPCSTR StringTableFr[];
+extern LPCSTR StringTableNo[];
+
+#if defined(WINELIB) && !defined(HAVE_WINE_CONSTRUCTOR)
+ VOID LIBWINE_Register_accel(void);
+ VOID LIBWINE_Register_Cz(void);
+ VOID LIBWINE_Register_Da(void);
+ VOID LIBWINE_Register_De(void);
+ VOID LIBWINE_Register_Es(void);
+ VOID LIBWINE_Register_En(void);
+ VOID LIBWINE_Register_Fi(void);
+ VOID LIBWINE_Register_Fr(void);
+ VOID LIBWINE_Register_No(void);
+#endif
+
+#endif /* !RC_INVOKED */
+
+/* Menu */
+
+#define PM_NEW 100
+#define PM_OPEN 101
+#define PM_MOVE 102
+#define PM_COPY 103
+#define PM_DELETE 104
+#define PM_ATTRIBUTES 105
+#define PM_EXECUTE 107
+#define PM_EXIT 108
+
+#define PM_AUTO_ARRANGE 200
+#define PM_MIN_ON_RUN 201
+#define PM_SAVE_SETTINGS 203
+
+#define PM_OVERLAP 300
+#define PM_SIDE_BY_SIDE 301
+#define PM_ARRANGE 302
+#define PM_FIRST_CHILD 3030
+
+#define PM_En 400
+#define PM_Es 401
+#define PM_De 402
+#define PM_No 403
+#define PM_Fr 404
+#define PM_Fi 405
+#define PM_Da 406
+#define PM_Cz 407
+
+#define PM_CONTENTS 501
+#define PM_SEARCH 502
+#define PM_HELPONHELP 503
+#define PM_TUTORIAL 504
+
+#define PM_LICENSE 510
+#define PM_NO_WARRANTY 511
+#define PM_ABOUT_WINE 512
+
+/* Dialog `New' */
+
+/* RADIOBUTTON: The next two must be in sequence */
+#define PM_NEW_GROUP 1000
+#define PM_NEW_PROGRAM 1001
+#define PM_NEW_GROUP_TXT 1002
+#define PM_NEW_PROGRAM_TXT 1003
+
+/* Dialogs `Copy', `Move' */
+
+#define PM_PROGRAM 1200
+#define PM_FROM_GROUP 1201
+#define PM_TO_GROUP 1202
+#define PM_TO_GROUP_TXT 1203
+
+/* Dialogs `Group attributes' */
+
+#define PM_DESCRIPTION 1500
+#define PM_DESCRIPTION_TXT 1501
+#define PM_FILE 1502
+#define PM_FILE_TXT 1503
+
+/* Dialogs `Program attributes' */
+#define PM_COMMAND_LINE 1510
+#define PM_COMMAND_LINE_TXT 1511
+#define PM_DIRECTORY 1512
+#define PM_DIRECTORY_TXT 1513
+#define PM_HOT_KEY 1514
+#define PM_HOT_KEY_TXT 1515
+#define PM_ICON 1516
+#define PM_OTHER_SYMBOL 1517
+
+/* Dialog `Symbol' */
+
+#define PM_ICON_FILE 1520
+#define PM_ICON_FILE_TXT 1521
+#define PM_SYMBOL_LIST 1522
+#define PM_SYMBOL_LIST_TXT 1523
+
+/* Dialog `Execute' */
+
+#define PM_COMMAND 1600
+#define PM_SYMBOL 1601
+#define PM_BROWSE 1602
+#define PM_HELP 1603
+
+#endif /* PROGMAN_H */
+
+/* Local Variables: */
+/* c-file-style: "GNU" */
+/* End: */
diff --git a/programs/progman/program.c b/programs/progman/program.c
new file mode 100644
index 0000000..adf30ed
--- /dev/null
+++ b/programs/progman/program.c
@@ -0,0 +1,356 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid
+ */
+
+#include <windows.h>
+#include "progman.h"
+
+/***********************************************************************
+ *
+ * PROGRAM_ProgramWndProc
+ */
+
+static LRESULT PROGRAM_ProgramWndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_NCLBUTTONDOWN:
+ {
+ HLOCAL hProgram = (HLOCAL) GetWindowLong(hWnd, 0);
+ PROGRAM *program = LocalLock(hProgram);
+ GROUP *group = LocalLock(program->hGroup);
+ group->hActiveProgram = hProgram;
+ EnableMenuItem(Globals.hFileMenu, PM_MOVE , MF_ENABLED);
+ EnableMenuItem(Globals.hFileMenu, PM_COPY , MF_ENABLED);
+ break;
+ }
+ case WM_NCLBUTTONDBLCLK:
+ {
+ PROGRAM_ExecuteProgram((HLOCAL) GetWindowLong(hWnd, 0));
+ return(0);
+ }
+
+ case WM_PAINT:
+ {
+ PROGRAM *program;
+ PAINTSTRUCT ps;
+ HDC hdc;
+ hdc = BeginPaint(hWnd,&ps);
+ program = LocalLock((HLOCAL) GetWindowLong(hWnd, 0));
+ if (program->hIcon)
+ DrawIcon(hdc, 0, 0, program->hIcon);
+ EndPaint(hWnd,&ps);
+ break;
+ }
+ }
+ return(DefWindowProc(hWnd, msg, wParam, lParam));
+}
+
+/***********************************************************************
+ *
+ * PROGRAM_RegisterProgramWinClass
+ */
+
+ATOM PROGRAM_RegisterProgramWinClass()
+{
+ WNDCLASS class;
+
+ class.style = CS_HREDRAW | CS_VREDRAW;
+ class.lpfnWndProc = PROGRAM_ProgramWndProc;
+ class.cbClsExtra = 0;
+ class.cbWndExtra = sizeof(LONG);
+ class.hInstance = Globals.hInstance;
+ class.hIcon = 0;
+ class.hCursor = LoadCursor (0, IDC_ARROW);
+ class.hbrBackground = GetStockObject (WHITE_BRUSH);
+ class.lpszMenuName = 0;
+ class.lpszClassName = STRING_PROGRAM_WIN_CLASS_NAME;
+
+ return RegisterClass(&class);
+}
+
+/***********************************************************************
+ *
+ * PROGRAM_NewProgram
+ */
+
+VOID PROGRAM_NewProgram(HLOCAL hGroup)
+{
+ INT nCmdShow = SW_SHOWNORMAL;
+ INT nHotKey = 0;
+ INT nIconIndex = 0;
+ CHAR szName[MAX_PATHNAME_LEN] = "";
+ CHAR szCmdLine[MAX_PATHNAME_LEN] = "";
+ CHAR szIconFile[MAX_PATHNAME_LEN] = "";
+ CHAR szWorkDir[MAX_PATHNAME_LEN] = "";
+ HICON hIcon = 0;
+
+ if (!DIALOG_ProgramAttributes(szName, szCmdLine, szWorkDir, szIconFile,
+ &hIcon, &nIconIndex, &nHotKey,
+ &nCmdShow, MAX_PATHNAME_LEN))
+ return;
+
+ if (!hIcon) hIcon = LoadIcon(0, MAKEINTRESOURCE(OIC_WINEICON));
+
+
+ if (!PROGRAM_AddProgram(hGroup, hIcon, szName, 0, 0, szCmdLine, szIconFile,
+ nIconIndex, szWorkDir, nHotKey, nCmdShow))
+ return;
+
+ GRPFILE_WriteGroupFile(hGroup);
+}
+
+/***********************************************************************
+ *
+ * PROGRAM_ModifyProgram
+ */
+
+VOID PROGRAM_ModifyProgram(HLOCAL hProgram)
+{
+ PROGRAM *program = LocalLock(hProgram);
+ CHAR szName[MAX_PATHNAME_LEN];
+ CHAR szCmdLine[MAX_PATHNAME_LEN];
+ CHAR szIconFile[MAX_PATHNAME_LEN];
+ CHAR szWorkDir[MAX_PATHNAME_LEN];
+
+ lstrcpyn(szName, LocalLock(program->hName), MAX_PATHNAME_LEN);
+ lstrcpyn(szCmdLine, LocalLock(program->hCmdLine), MAX_PATHNAME_LEN);
+ lstrcpyn(szIconFile, LocalLock(program->hIconFile), MAX_PATHNAME_LEN);
+ lstrcpyn(szWorkDir, LocalLock(program->hWorkDir), MAX_PATHNAME_LEN);
+
+ if (!DIALOG_ProgramAttributes(szName, szCmdLine, szWorkDir, szIconFile,
+ &program->hIcon, &program->nIconIndex,
+ &program->nHotKey, &program->nCmdShow,
+ MAX_PATHNAME_LEN))
+ return;
+
+ MAIN_ReplaceString(&program->hName, szName);
+ MAIN_ReplaceString(&program->hCmdLine, szCmdLine);
+ MAIN_ReplaceString(&program->hIconFile, szIconFile);
+ MAIN_ReplaceString(&program->hWorkDir, szWorkDir);
+
+ SetWindowText(program->hWnd, szName);
+ UpdateWindow(program->hWnd);
+
+ GRPFILE_WriteGroupFile(program->hGroup);
+
+ return;
+}
+
+/***********************************************************************
+ *
+ * PROGRAM_AddProgram
+ */
+
+HLOCAL PROGRAM_AddProgram(HLOCAL hGroup, HICON hIcon, LPCSTR lpszName,
+ INT x, INT y, LPCSTR lpszCmdLine,
+ LPCSTR lpszIconFile, INT nIconIndex,
+ LPCSTR lpszWorkDir, INT nHotKey, INT nCmdShow)
+{
+ GROUP *group = LocalLock(hGroup);
+ PROGRAM *program;
+ HLOCAL hPrior, *p;
+ HLOCAL hProgram = LocalAlloc(LMEM_FIXED, sizeof(PROGRAM));
+ HLOCAL hName = LocalAlloc(LMEM_FIXED, 1 + lstrlen(lpszName));
+ HLOCAL hCmdLine = LocalAlloc(LMEM_FIXED, 1 + lstrlen(lpszCmdLine));
+ HLOCAL hIconFile = LocalAlloc(LMEM_FIXED, 1 + lstrlen(lpszIconFile));
+ HLOCAL hWorkDir = LocalAlloc(LMEM_FIXED, 1 + lstrlen(lpszWorkDir));
+ if (!hProgram || !hName || !hCmdLine || !hIconFile || !hWorkDir)
+ {
+ MAIN_OutOfMemoryError();
+ if (hProgram) LocalFree(hProgram);
+ if (hName) LocalFree(hName);
+ if (hCmdLine) LocalFree(hCmdLine);
+ if (hIconFile) LocalFree(hIconFile);
+ if (hWorkDir) LocalFree(hWorkDir);
+ return(0);
+ }
+ hmemcpy(LocalLock(hName), lpszName, 1 + lstrlen(lpszName));
+ hmemcpy(LocalLock(hCmdLine), lpszCmdLine, 1 + lstrlen(lpszCmdLine));
+ hmemcpy(LocalLock(hIconFile), lpszIconFile, 1 + lstrlen(lpszIconFile));
+ hmemcpy(LocalLock(hWorkDir), lpszWorkDir, 1 + lstrlen(lpszWorkDir));
+
+ group->hActiveProgram = hProgram;
+
+ hPrior = 0;
+ p = &group->hPrograms;
+ while (*p)
+ {
+ hPrior = *p;
+ p = &((PROGRAM*)LocalLock(hPrior))->hNext;
+ }
+ *p = hProgram;
+
+ program = LocalLock(hProgram);
+ program->hGroup = hGroup;
+ program->hPrior = hPrior;
+ program->hNext = 0;
+ program->hName = hName;
+ program->hCmdLine = hCmdLine;
+ program->hIconFile = hIconFile;
+ program->nIconIndex = nIconIndex;
+ program->hWorkDir = hWorkDir;
+ program->hIcon = hIcon;
+ program->nCmdShow = nCmdShow;
+ program->nHotKey = nHotKey;
+
+ program->hWnd =
+ CreateWindow (STRING_PROGRAM_WIN_CLASS_NAME, (LPSTR)lpszName,
+ WS_CHILD | WS_OVERLAPPEDWINDOW,
+ x, y, CW_USEDEFAULT, CW_USEDEFAULT,
+ group->hWnd, 0, Globals.hInstance, 0);
+
+ SetWindowLong(program->hWnd, 0, (LONG) hProgram);
+
+ ShowWindow (program->hWnd, SW_SHOWMINIMIZED);
+ UpdateWindow (program->hWnd);
+
+ return hProgram;
+}
+
+/***********************************************************************
+ *
+ * PROGRAM_CopyMoveProgram
+ */
+
+VOID PROGRAM_CopyMoveProgram(HLOCAL hProgram, BOOL bMove)
+{
+ PROGRAM *program = LocalLock(hProgram);
+ GROUP *fromgroup = LocalLock(program->hGroup);
+ HLOCAL hGroup = DIALOG_CopyMove(LocalLock(program->hName),
+ LocalLock(fromgroup->hName), bMove);
+ if (!hGroup) return;
+
+ /* FIXME shouldn't be necessary */
+ OpenIcon(((GROUP*)LocalLock(hGroup))->hWnd);
+
+ if (!PROGRAM_AddProgram(hGroup,
+#if 0
+ CopyIcon(program->hIcon),
+#else
+ program->hIcon,
+#endif
+ LocalLock(program->hName),
+ program->x, program->y,
+ LocalLock(program->hCmdLine),
+ LocalLock(program->hIconFile),
+ program->nIconIndex,
+ LocalLock(program->hWorkDir),
+ program->nHotKey, program->nCmdShow)) return;
+ GRPFILE_WriteGroupFile(hGroup);
+
+ if (bMove) PROGRAM_DeleteProgram(hProgram, TRUE);
+}
+
+/***********************************************************************
+ *
+ * PROGRAM_ExecuteProgram
+ */
+
+VOID PROGRAM_ExecuteProgram(HLOCAL hProgram)
+{
+ PROGRAM *program = LocalLock(hProgram);
+ LPSTR lpszCmdLine = LocalLock(program->hCmdLine);
+ LPSTR lpszWorkDir = LocalLock(program->hWorkDir);
+
+ /* FIXME set working direktory */
+ lpszWorkDir = lpszWorkDir;
+
+ WinExec(lpszCmdLine, program->nCmdShow);
+ if (Globals.bMinOnRun) CloseWindow(Globals.hMainWnd);
+}
+
+/***********************************************************************
+ *
+ * PROGRAM_DeleteProgram
+ */
+
+VOID PROGRAM_DeleteProgram(HLOCAL hProgram, BOOL bUpdateGrpFile)
+{
+ PROGRAM *program = LocalLock(hProgram);
+ GROUP *group = LocalLock(program->hGroup);
+
+ group->hActiveProgram = 0;
+
+ if (program->hPrior)
+ ((PROGRAM*)LocalLock(program->hPrior))->hNext = program->hNext;
+ else
+ ((GROUP*)LocalLock(program->hGroup))->hPrograms = program->hNext;
+
+ if (program->hNext)
+ ((PROGRAM*)LocalLock(program->hNext))->hPrior = program->hPrior;
+
+ if (bUpdateGrpFile)
+ GRPFILE_WriteGroupFile(program->hGroup);
+
+ DestroyWindow(program->hWnd);
+#if 0
+ if (program->hIcon)
+ DestroyIcon(program->hIcon);
+#endif
+ LocalFree(program->hName);
+ LocalFree(program->hCmdLine);
+ LocalFree(program->hIconFile);
+ LocalFree(program->hWorkDir);
+ LocalFree(hProgram);
+}
+
+/***********************************************************************
+ *
+ * PROGRAM_FirstProgram
+ */
+
+HLOCAL PROGRAM_FirstProgram(HLOCAL hGroup)
+{
+ GROUP *group;
+ if (!hGroup) return(0);
+ group = LocalLock(hGroup);
+ return(group->hPrograms);
+}
+
+/***********************************************************************
+ *
+ * PROGRAM_NextProgram
+ */
+
+HLOCAL PROGRAM_NextProgram(HLOCAL hProgram)
+{
+ PROGRAM *program;
+ if (!hProgram) return(0);
+ program = LocalLock(hProgram);
+ return(program->hNext);
+}
+
+/***********************************************************************
+ *
+ * PROGRAM_ActiveProgram
+ */
+
+HLOCAL PROGRAM_ActiveProgram(HLOCAL hGroup)
+{
+ GROUP *group;
+ if (!hGroup) return(0);
+ group = LocalLock(hGroup);
+ if (IsIconic(group->hWnd)) return(0);
+
+ return(group->hActiveProgram);
+}
+
+/***********************************************************************
+ *
+ * PROGRAM_ProgramName
+ */
+
+LPCSTR PROGRAM_ProgramName(HLOCAL hProgram)
+{
+ PROGRAM *program;
+ if (!hProgram) return(0);
+ program = LocalLock(hProgram);
+ return(LocalLock(program->hName));
+}
+
+/* Local Variables: */
+/* c-file-style: "GNU" */
+/* End: */
diff --git a/programs/progman/string.c b/programs/progman/string.c
new file mode 100644
index 0000000..a040855
--- /dev/null
+++ b/programs/progman/string.c
@@ -0,0 +1,92 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid
+ */
+
+#include <windows.h>
+#include "progman.h"
+
+/* Class names */
+
+CHAR STRING_MAIN_WIN_CLASS_NAME[] = "PMMain";
+CHAR STRING_MDI_WIN_CLASS_NAME[] = "MDICLIENT";
+CHAR STRING_GROUP_WIN_CLASS_NAME[] = "PMGroup";
+CHAR STRING_PROGRAM_WIN_CLASS_NAME[] = "PMProgram";
+
+/* Resource names */
+/* Xx will be overwritten with En, ... */
+CHAR STRING_ACCEL[] = "ACCEL";
+CHAR STRING_MAIN_Xx[] = "MENU_Xx";
+CHAR STRING_NEW_Xx[] = "DIALOG_NEW_Xx";
+CHAR STRING_OPEN_Xx[] = "DIALOG_OPEN_Xx";
+CHAR STRING_MOVE_Xx[] = "DIALOG_MOVE_Xx";
+CHAR STRING_COPY_Xx[] = "DIALOG_COPY_Xx";
+CHAR STRING_DELETE_Xx[] = "DIALOG_DELETE_Xx";
+CHAR STRING_GROUP_Xx[] = "DIALOG_GROUP_Xx";
+CHAR STRING_PROGRAM_Xx[] = "DIALOG_PROGRAM_Xx";
+CHAR STRING_SYMBOL_Xx[] = "DIALOG_SYMBOL_Xx";
+CHAR STRING_EXECUTE_Xx[] = "DIALOG_EXECUTE_Xx";
+
+static LPCSTR StringTableEn[];
+static LPCSTR StringTableDe[];
+
+VOID STRING_SelectLanguage(LPCSTR lang)
+{
+ /* Change string table */
+ Globals.StringTable = StringTableEn;
+ if (!lstrcmp(lang, "De")) Globals.StringTable = StringTableDe;
+
+ SetWindowText(Globals.hMainWnd, STRING_PROGRAM_MANAGER);
+
+ /* Change Resource names */
+ lstrcpyn(STRING_MAIN_Xx + sizeof(STRING_MAIN_Xx) - 3, lang, 3);
+ lstrcpyn(STRING_NEW_Xx + sizeof(STRING_NEW_Xx) - 3, lang, 3);
+ lstrcpyn(STRING_OPEN_Xx + sizeof(STRING_OPEN_Xx) - 3, lang, 3);
+ lstrcpyn(STRING_MOVE_Xx + sizeof(STRING_MOVE_Xx) - 3, lang, 3);
+ lstrcpyn(STRING_COPY_Xx + sizeof(STRING_COPY_Xx) - 3, lang, 3);
+ lstrcpyn(STRING_DELETE_Xx + sizeof(STRING_DELETE_Xx) - 3, lang, 3);
+ lstrcpyn(STRING_GROUP_Xx + sizeof(STRING_GROUP_Xx) - 3, lang, 3);
+ lstrcpyn(STRING_PROGRAM_Xx + sizeof(STRING_PROGRAM_Xx) - 3, lang, 3);
+ lstrcpyn(STRING_SYMBOL_Xx + sizeof(STRING_SYMBOL_Xx) - 3, lang, 3);
+ lstrcpyn(STRING_EXECUTE_Xx + sizeof(STRING_EXECUTE_Xx) - 3, lang, 3);
+
+ /* Destroy old menu */
+ if (Globals.hMainMenu)
+ {
+ SendMessage(Globals.hMDIWnd, WM_MDISETMENU, (WPARAM) NULL, (LPARAM) NULL);
+#if 0 /* FIXME when MDISetMenu is complete */
+ DestroyMenu(Globals.hMainMenu);
+#endif
+ }
+
+ /* Create new menu */
+ Globals.hMainMenu = LoadMenu(Globals.hInstance, STRING_MAIN_Xx);
+ if (Globals.hMainMenu)
+ {
+ Globals.hFileMenu = GetSubMenu(Globals.hMainMenu, 0);
+ Globals.hOptionMenu = GetSubMenu(Globals.hMainMenu, 1);
+ Globals.hWindowsMenu = GetSubMenu(Globals.hMainMenu, 2);
+
+ if (Globals.hMDIWnd)
+ SendMessage(Globals.hMDIWnd, WM_MDISETMENU,
+ (WPARAM) Globals.hMainMenu,
+ (LPARAM) Globals.hWindowsMenu);
+ else SetMenu(Globals.hMainWnd, Globals.hMainMenu);
+ }
+ /* Unsupported language */
+ else if(lstrcmp(lang, "En")) STRING_SelectLanguage("En");
+ else
+ {
+ MessageBox(Globals.hMainWnd, "No language found", "FATAL ERROR", MB_OK);
+ PostQuitMessage(1);
+ }
+
+ /* have to be last because of
+ * the possible recursion */
+ Globals.lpszLanguage = lang;
+}
+
+/* Local Variables: */
+/* c-file-style: "GNU" */
+/* End: */
diff --git a/programs/progman/winexec.c b/programs/progman/winexec.c
new file mode 100644
index 0000000..722576c
--- /dev/null
+++ b/programs/progman/winexec.c
@@ -0,0 +1,91 @@
+#ifdef WINELIB
+#include <unistd.h>
+#include <string.h>
+#include "windows.h"
+#include "winbase.h"
+#include "options.h"
+#include "dos_fs.h"
+#include "debug.h"
+#include "progman.h"
+
+#define MAX_CMDLINE_SIZE 256
+
+/* FIXME should use WinExec from -lwine */
+
+HANDLE ProgmanWinExec( LPSTR lpCmdLine, WORD nCmdShow )
+{
+ char wine[MAX_CMDLINE_SIZE];
+ char filename[MAX_CMDLINE_SIZE], *p;
+ char cmdline[MAX_CMDLINE_SIZE];
+ const char *argv[10], **argptr;
+ const char *unixfilename;
+ int simplename = 1;
+
+ if (fork()) return(INVALID_HANDLE_VALUE);
+
+ strncpy( filename, lpCmdLine, MAX_CMDLINE_SIZE );
+ filename[MAX_CMDLINE_SIZE-1] = '\0';
+ for (p = filename; *p && (*p != ' ') && (*p != '\t'); p++)
+ if ((*p == ':') || (*p == ':') || (*p == '/')) simplename = 0;
+ if (*p)
+ {
+ strncpy( cmdline, p + 1, 128 );
+ cmdline[127] = '\0';
+ }
+ else cmdline[0] = '\0';
+ *p = '\0';
+
+ if (simplename) unixfilename = filename;
+ else unixfilename = DOSFS_GetUnixFileName(filename, 0);
+
+ argptr = argv;
+ *argptr++ = unixfilename;
+ if (nCmdShow == SW_SHOWMINIMIZED) *argptr++ = "-iconic";
+ if (cmdline[0]) *argptr++ = cmdline;
+ *argptr++ = 0;
+ execvp(argv[0], (char**)argv);
+
+ PROFILE_GetWineIniString("progman", "wine", "wine",
+ wine, sizeof(wine));
+ argptr = argv;
+ *argptr++ = wine;
+ *argptr++ = "-language";
+ *argptr++ = Globals.lpszLanguage;
+ if (nCmdShow == SW_SHOWMINIMIZED) *argptr++ = "-iconic";
+ *argptr++ = lpCmdLine;
+ *argptr++ = 0;
+ execvp(argv[0] , (char**)argv);
+
+ printf("Cannot exec `%s %s %s%s %s'\n",
+ wine, "-language", Globals.lpszLanguage,
+ nCmdShow == SW_SHOWMINIMIZED ? " -iconic" : "",
+ lpCmdLine);
+ exit(1);
+}
+
+BOOL ProgmanWinHelp(HWND hWnd, LPSTR lpHelpFile, WORD wCommand, DWORD dwData)
+{
+ char str[256];
+ dprintf_exec(stddeb,"WinHelp(%s, %u, %lu)\n",
+ lpHelpFile, wCommand, dwData);
+ switch(wCommand) {
+ case 0:
+ case HELP_HELPONHELP:
+ GetWindowsDirectory(str, sizeof(str));
+ strcat(str, "\\winhelp.exe winhelp.hlp");
+ dprintf_exec(stddeb,"'%s'\n", str);
+ break;
+ case HELP_INDEX:
+ GetWindowsDirectory(str, sizeof(str));
+ strcat(str, "\\winhelp.exe ");
+ strcat(str, lpHelpFile);
+ dprintf_exec(stddeb,"'%s'\n", str);
+ break;
+ default:
+ return FALSE;
+ }
+ WinExec(str, SW_SHOWNORMAL);
+ return(TRUE);
+}
+
+#endif