* README: Update TODO's.
* choose.cc (set_existence): Delete non installed packages with no
mirrors.
(fill_missing_category): Fix an off-by-one error.
(default_trust): Ditto. Also delete any unused categories.
(view::init_headers): Fix an off-by-one error.
(set_view_mode): Ditto.
(set_view_mode): Ditto.
(create_listview): Ditto.
(dialog_cmd): Ditto.
(do_choose): Ditto.
* io_stream.cc: Indent.
* io_stream.h: Ditto.
* package_db.cc: Ditto.
* package_meta.h: Const correctness for SDesc ();
* proppage.cc: Run d2u and indent.
* propsheet.cc: Run d2u and indent.
* window.cc: Run d2u and indent.
* window.h: Run d2u and indent.
+2002-01-01 Robert Collins <rbtcollins@hotmail.com>
+
+ * README: Update TODO's.
+ * choose.cc (set_existence): Delete non installed packages with no
+ mirrors.
+ (fill_missing_category): Fix an off-by-one error.
+ (default_trust): Ditto. Also delete any unused categories.
+ (view::init_headers): Fix an off-by-one error.
+ (set_view_mode): Ditto.
+ (set_view_mode): Ditto.
+ (create_listview): Ditto.
+ (dialog_cmd): Ditto.
+ (do_choose): Ditto.
+ * io_stream.cc: Indent.
+ * io_stream.h: Ditto.
+ * package_db.cc: Ditto.
+ * package_meta.h: Const correctness for SDesc ();
+ * proppage.cc: Run d2u and indent.
+ * propsheet.cc: Run d2u and indent.
+ * window.cc: Run d2u and indent.
+ * window.h: Run d2u and indent.
+
2001-12-28 Christopher Faylor <cgf@redhat.com>
* Makefile.in (iniparse.o): Accommodate newer bisons.
TODO:
* Src tickbox /source only can be confusing.
-* file magic detection. - partially complete.
* support rpm/deb files for reading the package from. (To allow the maintainers the use of rpm/deb tools to create packages.)
* make a librar(y|ies) for setup and cygcheck to use containing
1) Something to translate POSIX -> native. Currently called "cygpath"
* build-depends
* FTP control connections should be closed when we are awaiting user input.
* Show a sdesc for each category
- * ini.cc: add field in setup.ini to specify whether package is installed by default, or not.
* Add friendly error reporting to simpsock.cc
* scan newly installed files for README files, show list to user, let them read them if they want.
* Mouse wheel support broken/missing for *some* users.
happens via the reinstall/redo already - perhaps this is "done".)
* Make skip only ever appear for non-installed packages.
* skip sould be followed by the <prec/curr/exp> from the radio buttons, not by prev.
+ * Src tickbox /source only can be confusing.
+ * ini.cc: add field in setup.ini to specify whether package is installed by default, or not. (base category does this)
+
static void
set_existence ()
{
- /* FIXME:
- iterate through the package list, and delete packages that are
- * Not installed
- * have no mirror site
- and then do the same for categories with no packages.
- */
+ packagedb db;
+ /* Remove packages that are in the db, not installed, and have no
+ mirror info. */
+ size_t n = 1;
+ while (n <= db.packages.number ())
+ {
+ packagemeta & pkg = *db.packages[n];
+ bool mirrors = false;
+ size_t o = 1;
+ while (o <= pkg.versions.number () && !mirrors)
+ {
+ packageversion & ver = *pkg.versions[o];
+ if (ver.bin.sites.number () || ver.src.sites.number ())
+ mirrors = true;
+ ++o;
+ }
+ if (!pkg.installed && !mirrors)
+ {
+ packagemeta * pkgm = db.packages.removebyindex (n);
+ delete pkgm;
+ }
+ else
+ ++n;
+ }
}
static void
fill_missing_category ()
{
packagedb db;
- for (size_t n = 1; n < db.packages.number (); n++)
+ for (size_t n = 1; n <= db.packages.number (); n++)
{
packagemeta & pkg = *db.packages[n];
if (!pkg.Categories.number ())
{
deftrust = trust;
packagedb db;
- for (size_t n = 1; n < db.packages.number (); n++)
+ for (size_t n = 1; n <= db.packages.number (); n++)
{
packagemeta & pkg = *db.packages[n];
if (pkg.installed
InvalidateRect (h, &r, TRUE);
if (nextbutton)
SetFocus (nextbutton);
+ // and then do the same for categories with no packages.
+ size_t n = 1;
+ while (n <= db.categories.number ())
+ {
+ if (!db.categories[n]->packages)
+ {
+ Category * cat = db.categories.removebyindex (n);
+ delete cat;
+ }
+ else
+ ++n;
+ }
}
void
/* src checkbox */
note_width (headers, dc, 0, HMARGIN + 11, src_col);
packagedb db;
- for (size_t n = 1; n < db.packages.number (); n++)
+ for (size_t n = 1; n <= db.packages.number (); n++)
{
packagemeta & pkg = *db.packages[n];
if (pkg.installed)
switch (chooser->get_view_mode ())
{
case VIEW_PACKAGE:
- for (size_t n = 1; n < db.packages.number (); n++)
+ for (size_t n = 1; n <= db.packages.number (); n++)
{
packagemeta & pkg = *db.packages[n];
if ((!pkg.desired && pkg.installed)
}
break;
case VIEW_PACKAGE_FULL:
- for (size_t n = 1; n < db.packages.number (); n++)
+ for (size_t n = 1; n <= db.packages.number (); n++)
{
packagemeta & pkg = *db.packages[n];
chooser->insert_pkg (pkg);
log (LOG_BABBLE, "Failed to set View button caption %ld",
GetLastError ());
packagedb db;
- for (size_t n = 1; n < db.packages.number (); n++)
+ for (size_t n = 1; n <= db.packages.number (); n++)
{
packagemeta & pkg = *db.packages[n];
add_required (pkg);
{
case IDC_CHOOSE_PREV:
default_trust (lv, TRUST_PREV);
- for (size_t n = 1; n < db.packages.number (); n++)
+ for (size_t n = 1; n <= db.packages.number (); n++)
{
packagemeta & pkg = *db.packages[n];
add_required (pkg);
break;
case IDC_CHOOSE_CURR:
default_trust (lv, TRUST_CURR);
- for (size_t n = 1; n < db.packages.number (); n++)
+ for (size_t n = 1; n <= db.packages.number (); n++)
{
packagemeta & pkg = *db.packages[n];
add_required (pkg);
break;
case IDC_CHOOSE_EXP:
default_trust (lv, TRUST_TEST);
- for (size_t n = 1; n < db.packages.number (); n++)
+ for (size_t n = 1; n <= db.packages.number (); n++)
{
packagemeta & pkg = *db.packages[n];
add_required (pkg);
log (LOG_BABBLE, "Chooser results...");
packagedb db;
- for (size_t n = 1; n < db.packages.number (); n++)
+ for (size_t n = 1; n <= db.packages.number (); n++)
{
packagemeta & pkg = *db.packages[n];
// static const char *infos[] = { "nada", "prev", "curr", "test" };
return 0;
}
-ssize_t
-io_stream::copy (io_stream *in, io_stream *out)
+ssize_t io_stream::copy (io_stream * in, io_stream * out)
{
if (!in || !out)
return -1;
- char buffer[16384];
- ssize_t countin, countout;
+ char
+ buffer[16384];
+ ssize_t
+ countin,
+ countout;
while ((countin = in->read (buffer, 16384)) > 0)
{
countout = out->write (buffer, countin);
if (countout != countin)
- {
- log (LOG_TIMESTAMP, "io_stream::copy failed to write %ld bytes", countin);
- return countout ? countout : -1;
- }
+ {
+ log (LOG_TIMESTAMP, "io_stream::copy failed to write %ld bytes",
+ countin);
+ return countout ? countout : -1;
+ }
}
/* TODO:
log (LOG_TIMESTAMP, "io_stream::~io_stream called");
return;
}
-
-
/* if you are still needing these hints... give up now! */
virtual ~ io_stream () = 0;
protected:
- void operator= (const io_stream &);
- io_stream () {};
- io_stream (const io_stream &);
+ void operator= (const io_stream &);
+ io_stream ()
+ {
+ };
+ io_stream (const io_stream &);
private:
static int move_copy (char const *, char const *);
};
packagedb::packagedb ()
{
- io_stream * db = 0;
+ io_stream *db = 0;
if (!installeddbread)
{
/* no parameters. Read in the local installation database. */
ndb->write ("INSTALLED.DB 2\n", strlen ("INSTALLED.DB 2\n"));
for (size_t n = 1; n < packages.number (); n++)
{
- packagemeta &pkgm = * packages[n];
- if (pkgm.installed)
- {
- char line[2048];
-
- /* size here is irrelevant - as we can assume that this install source
- * no longer exists, and it does not correlate to used disk space
- * also note that we are writing a fictional install source
- * to keep cygcheck happy.
- */
- sprintf (line, "%s %s %d\n", pkgm.name,
- concat (pkgm.name, "-",
- pkgm.installed->Canonical_version (),
- ".tar.bz2", 0), 0);
- ndb->write (line, strlen (line));
- }
+ packagemeta & pkgm = *packages[n];
+ if (pkgm.installed)
+ {
+ char line[2048];
+
+ /* size here is irrelevant - as we can assume that this install source
+ * no longer exists, and it does not correlate to used disk space
+ * also note that we are writing a fictional install source
+ * to keep cygcheck happy.
+ */
+ sprintf (line, "%s %s %d\n", pkgm.name,
+ concat (pkgm.name, "-",
+ pkgm.installed->Canonical_version (),
+ ".tar.bz2", 0), 0);
+ ndb->write (line, strlen (line));
+ }
}
delete ndb;
return 0;
}
-int packagedb::installeddbread = 0;
-list < packagemeta, char const *, strcasecmp > packagedb::packages;
+int
+ packagedb::installeddbread =
+ 0;
+list < packagemeta, char const *,
+ strcasecmp >
+ packagedb::packages;
list < Category, char const *,
strcasecmp >
packagedb::categories;
-PackageDBActions packagedb::task = PackageDB_Install;
+PackageDBActions
+ packagedb::task =
+ PackageDB_Install;
}
char const *
-packagemeta::SDesc ()
+packagemeta::SDesc () const
{
return versions[1]->SDesc ();
};
strcpy (installed_from, installedfrom);
};
-
~packagemeta ()
{
delete[] name;
char *installed_from;
/* SDesc is global in theory, across all package versions.
LDesc is not: it can be different per version */
- char const *SDesc ();
+ char const *SDesc () const;
/* what categories does this package belong in. Note that if multiple versions
* of a package disagree.... the first one read in will take precedence.
*/
-/*\r
- * Copyright (c) 2001, Gary R. Van Sickle.\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * A copy of the GNU General Public License can be found at\r
- * http://www.gnu.org/\r
- *\r
- * Written by Gary R. Van Sickle <g.r.vansickle@worldnet.att.net>\r
- *\r
- */\r
-\r
-// This is the implementation of the PropertyPage class. It works closely with the\r
-// PropSheet class to implement a single page of the property sheet.\r
-\r
-#include "proppage.h"\r
-#include "propsheet.h"\r
-#include "win32.h"\r
-\r
-bool\r
- PropertyPage::DoOnceForSheet =\r
- true;\r
-\r
-PropertyPage::PropertyPage ()\r
-{\r
- proc = NULL;\r
- cmdproc = NULL;\r
- IsFirst = false;\r
- IsLast = false;\r
-}\r
-\r
-PropertyPage::~PropertyPage ()\r
-{\r
-}\r
-\r
-bool\r
-PropertyPage::Create (int TemplateID)\r
-{\r
- return Create (NULL, NULL, TemplateID);\r
-}\r
-\r
-bool\r
-PropertyPage::Create (DLGPROC dlgproc, int TemplateID)\r
-{\r
- return Create (dlgproc, NULL, TemplateID);\r
-}\r
-\r
-bool\r
-PropertyPage::Create (DLGPROC dlgproc,\r
- BOOL (*cproc) (HWND h, int id, HWND hwndctl, UINT code),\r
- int TemplateID)\r
-{\r
- psp.dwSize = sizeof (PROPSHEETPAGE);\r
- psp.dwFlags = 0;\r
- psp.hInstance = GetInstance ();\r
- psp.pfnDlgProc = FirstDialogProcReflector;\r
- psp.pszTemplate = (LPCSTR) TemplateID;\r
- psp.lParam = (LPARAM) this;\r
- psp.pfnCallback = NULL;\r
-\r
- proc = dlgproc;\r
- cmdproc = cproc;\r
-\r
- return true;\r
-}\r
-\r
-BOOL CALLBACK\r
-PropertyPage::FirstDialogProcReflector (HWND hwnd, UINT message,\r
- WPARAM wParam, LPARAM lParam)\r
-{\r
- PropertyPage *This;\r
-\r
- if (message != WM_INITDIALOG)\r
- {\r
- // Don't handle anything until we get a WM_INITDIALOG message, which\r
- // will have our this pointer with it.\r
- return FALSE;\r
- }\r
-\r
- This = (PropertyPage *) (((PROPSHEETPAGE *) lParam)->lParam);\r
-\r
- SetWindowLong (hwnd, DWL_USER, (DWORD) This);\r
- SetWindowLong (hwnd, DWL_DLGPROC, (DWORD) DialogProcReflector);\r
-\r
- This->SetHWND (hwnd);\r
- return This->DialogProc (message, wParam, lParam);\r
-}\r
-\r
-BOOL CALLBACK\r
-PropertyPage::DialogProcReflector (HWND hwnd, UINT message, WPARAM wParam,\r
- LPARAM lParam)\r
-{\r
- PropertyPage *This;\r
-\r
- This = (PropertyPage *) GetWindowLong (hwnd, DWL_USER);\r
-\r
- return This->DialogProc (message, wParam, lParam);\r
-}\r
-\r
-BOOL CALLBACK\r
-PropertyPage::DialogProc (UINT message, WPARAM wParam, LPARAM lParam)\r
-{\r
- if (proc != NULL)\r
- {\r
- proc (GetHWND (), message, wParam, lParam);\r
- }\r
-\r
- bool retval;\r
-\r
- switch (message)\r
- {\r
- case WM_INITDIALOG:\r
- {\r
- OnInit ();\r
- // TRUE = Set focus to default control (in wParam).\r
- return TRUE;\r
- break;\r
- }\r
- case WM_NOTIFY:\r
- switch (((NMHDR FAR *) lParam)->code)\r
- {\r
- case PSN_APPLY:\r
- SetWindowLong (GetHWND (), DWL_MSGRESULT, PSNRET_NOERROR);\r
- return TRUE;\r
- break;\r
- case PSN_SETACTIVE:\r
- {\r
- if (DoOnceForSheet)\r
- {\r
- // Tell our parent PropSheet what its own HWND is.\r
- GetOwner ()->SetHWNDFromPage (((NMHDR FAR *) lParam)->\r
- hwndFrom);\r
- GetOwner ()->CenterWindow ();\r
- // Add a minimize box to the parent property sheet. We do this here\r
- // instead of in the sheet class mainly because it will work with either\r
- // modal or modeless sheets.\r
- LONG style =::GetWindowLong (((NMHDR FAR *) lParam)->hwndFrom,\r
- GWL_STYLE);\r
- ::SetWindowLong (((NMHDR FAR *) lParam)->hwndFrom, GWL_STYLE,\r
- style | WS_MINIMIZEBOX);\r
- DoOnceForSheet = false;\r
- }\r
-\r
- // Set the wizard buttons apropriately\r
- if (IsFirst)\r
- {\r
- // Disable "Back" on first page.\r
- GetOwner ()->SetButtons (PSWIZB_NEXT);\r
- //::PropSheet_SetWizButtons(((NMHDR FAR *) lParam)->hwndFrom, PSWIZB_NEXT);\r
- }\r
- else if (IsLast)\r
- {\r
- // Disable "Next", enable "Finish" on last page\r
- GetOwner ()->SetButtons (PSWIZB_BACK | PSWIZB_FINISH);\r
- //::PropSheet_SetWizButtons(((NMHDR FAR *) lParam)->hwndFrom, PSWIZB_BACK | PSWIZB_FINISH);\r
- }\r
- else\r
- {\r
- // Middle page, enable both "Next" and "Back" buttons\r
- GetOwner ()->SetButtons (PSWIZB_BACK | PSWIZB_NEXT);\r
- //::PropSheet_SetWizButtons(((NMHDR FAR *) lParam)->hwndFrom, PSWIZB_BACK | PSWIZB_NEXT);\r
- }\r
-\r
- OnActivate ();\r
-\r
- // 0 == Accept activation, -1 = Don't accept\r
- ::SetWindowLong (GetHWND (), DWL_MSGRESULT, 0);\r
- return TRUE;\r
- }\r
- break;\r
- case PSN_KILLACTIVE:\r
- OnDeactivate ();\r
- // FALSE = Allow deactivation\r
- SetWindowLong (GetHWND (), DWL_MSGRESULT, FALSE);\r
- return TRUE;\r
- break;\r
- case PSN_WIZNEXT:\r
- {\r
- LONG retval;\r
- retval = OnNext ();\r
- SetWindowLong (GetHWND (), DWL_MSGRESULT, retval);\r
- return TRUE;\r
- }\r
- break;\r
- case PSN_WIZBACK:\r
- {\r
- LONG retval;\r
- retval = OnBack ();\r
- SetWindowLong (GetHWND (), DWL_MSGRESULT, retval);\r
- return TRUE;\r
- }\r
- break;\r
- case PSN_WIZFINISH:\r
- retval = OnFinish ();\r
- // False = Allow the wizard to finish\r
- SetWindowLong (GetHWND (), DWL_MSGRESULT, FALSE);\r
- return TRUE;\r
- break;\r
- default:\r
- // Unrecognized notification\r
- return FALSE;\r
- break;\r
- }\r
- break;\r
- case WM_COMMAND:\r
- if (cmdproc != NULL)\r
- {\r
- return HANDLE_WM_COMMAND (GetHWND (), wParam, lParam, cmdproc);\r
- }\r
- break;\r
- default:\r
- break;\r
- }\r
-\r
- if ((message >= WM_APP) && (message < 0xC000))\r
- {\r
- // It's a private app message\r
- return OnMessageApp (message, wParam, lParam);\r
- }\r
-\r
- // Wasn't handled\r
- return FALSE;\r
-}\r
+/*
+ * Copyright (c) 2001, Gary R. Van Sickle.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * A copy of the GNU General Public License can be found at
+ * http://www.gnu.org/
+ *
+ * Written by Gary R. Van Sickle <g.r.vansickle@worldnet.att.net>
+ *
+ */
+
+// This is the implementation of the PropertyPage class. It works closely with the
+// PropSheet class to implement a single page of the property sheet.
+
+#include "proppage.h"
+#include "propsheet.h"
+#include "win32.h"
+
+bool PropertyPage::DoOnceForSheet = true;
+
+PropertyPage::PropertyPage ()
+{
+ proc = NULL;
+ cmdproc = NULL;
+ IsFirst = false;
+ IsLast = false;
+}
+
+PropertyPage::~PropertyPage ()
+{
+}
+
+bool PropertyPage::Create (int TemplateID)
+{
+ return Create (NULL, NULL, TemplateID);
+}
+
+bool PropertyPage::Create (DLGPROC dlgproc, int TemplateID)
+{
+ return Create (dlgproc, NULL, TemplateID);
+}
+
+bool
+ PropertyPage::Create (DLGPROC dlgproc,
+ BOOL (*cproc) (HWND h, int id, HWND hwndctl,
+ UINT code), int TemplateID)
+{
+ psp.dwSize = sizeof (PROPSHEETPAGE);
+ psp.dwFlags = 0;
+ psp.hInstance = GetInstance ();
+ psp.pfnDlgProc = FirstDialogProcReflector;
+ psp.pszTemplate = (LPCSTR) TemplateID;
+ psp.lParam = (LPARAM) this;
+ psp.pfnCallback = NULL;
+
+ proc = dlgproc;
+ cmdproc = cproc;
+
+ return true;
+}
+
+BOOL CALLBACK
+PropertyPage::FirstDialogProcReflector (HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ PropertyPage *This;
+
+ if (message != WM_INITDIALOG)
+ {
+ // Don't handle anything until we get a WM_INITDIALOG message, which
+ // will have our this pointer with it.
+ return FALSE;
+ }
+
+ This = (PropertyPage *) (((PROPSHEETPAGE *) lParam)->lParam);
+
+ SetWindowLong (hwnd, DWL_USER, (DWORD) This);
+ SetWindowLong (hwnd, DWL_DLGPROC, (DWORD) DialogProcReflector);
+
+ This->SetHWND (hwnd);
+ return This->DialogProc (message, wParam, lParam);
+}
+
+BOOL CALLBACK
+PropertyPage::DialogProcReflector (HWND hwnd, UINT message, WPARAM wParam,
+ LPARAM lParam)
+{
+ PropertyPage *This;
+
+ This = (PropertyPage *) GetWindowLong (hwnd, DWL_USER);
+
+ return This->DialogProc (message, wParam, lParam);
+}
+
+BOOL CALLBACK
+PropertyPage::DialogProc (UINT message, WPARAM wParam, LPARAM lParam)
+{
+ if (proc != NULL)
+ {
+ proc (GetHWND (), message, wParam, lParam);
+ }
+
+ bool retval;
+
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ {
+ OnInit ();
+ // TRUE = Set focus to default control (in wParam).
+ return TRUE;
+ break;
+ }
+ case WM_NOTIFY:
+ switch (((NMHDR FAR *) lParam)->code)
+ {
+ case PSN_APPLY:
+ SetWindowLong (GetHWND (), DWL_MSGRESULT, PSNRET_NOERROR);
+ return TRUE;
+ break;
+ case PSN_SETACTIVE:
+ {
+ if (DoOnceForSheet)
+ {
+ // Tell our parent PropSheet what its own HWND is.
+ GetOwner ()->SetHWNDFromPage (((NMHDR FAR *) lParam)->
+ hwndFrom);
+ GetOwner ()->CenterWindow ();
+ // Add a minimize box to the parent property sheet. We do this here
+ // instead of in the sheet class mainly because it will work with either
+ // modal or modeless sheets.
+ LONG style =::GetWindowLong (((NMHDR FAR *) lParam)->hwndFrom,
+ GWL_STYLE);
+ ::SetWindowLong (((NMHDR FAR *) lParam)->hwndFrom, GWL_STYLE,
+ style | WS_MINIMIZEBOX);
+ DoOnceForSheet = false;
+ }
+
+ // Set the wizard buttons apropriately
+ if (IsFirst)
+ {
+ // Disable "Back" on first page.
+ GetOwner ()->SetButtons (PSWIZB_NEXT);
+ //::PropSheet_SetWizButtons(((NMHDR FAR *) lParam)->hwndFrom, PSWIZB_NEXT);
+ }
+ else if (IsLast)
+ {
+ // Disable "Next", enable "Finish" on last page
+ GetOwner ()->SetButtons (PSWIZB_BACK | PSWIZB_FINISH);
+ //::PropSheet_SetWizButtons(((NMHDR FAR *) lParam)->hwndFrom, PSWIZB_BACK | PSWIZB_FINISH);
+ }
+ else
+ {
+ // Middle page, enable both "Next" and "Back" buttons
+ GetOwner ()->SetButtons (PSWIZB_BACK | PSWIZB_NEXT);
+ //::PropSheet_SetWizButtons(((NMHDR FAR *) lParam)->hwndFrom, PSWIZB_BACK | PSWIZB_NEXT);
+ }
+
+ OnActivate ();
+
+ // 0 == Accept activation, -1 = Don't accept
+ ::SetWindowLong (GetHWND (), DWL_MSGRESULT, 0);
+ return TRUE;
+ }
+ break;
+ case PSN_KILLACTIVE:
+ OnDeactivate ();
+ // FALSE = Allow deactivation
+ SetWindowLong (GetHWND (), DWL_MSGRESULT, FALSE);
+ return TRUE;
+ break;
+ case PSN_WIZNEXT:
+ {
+ LONG retval;
+ retval = OnNext ();
+ SetWindowLong (GetHWND (), DWL_MSGRESULT, retval);
+ return TRUE;
+ }
+ break;
+ case PSN_WIZBACK:
+ {
+ LONG retval;
+ retval = OnBack ();
+ SetWindowLong (GetHWND (), DWL_MSGRESULT, retval);
+ return TRUE;
+ }
+ break;
+ case PSN_WIZFINISH:
+ retval = OnFinish ();
+ // False = Allow the wizard to finish
+ SetWindowLong (GetHWND (), DWL_MSGRESULT, FALSE);
+ return TRUE;
+ break;
+ default:
+ // Unrecognized notification
+ return FALSE;
+ break;
+ }
+ break;
+ case WM_COMMAND:
+ if (cmdproc != NULL)
+ {
+ return HANDLE_WM_COMMAND (GetHWND (), wParam, lParam, cmdproc);
+ }
+ break;
+ default:
+ break;
+ }
+
+ if ((message >= WM_APP) && (message < 0xC000))
+ {
+ // It's a private app message
+ return OnMessageApp (message, wParam, lParam);
+ }
+
+ // Wasn't handled
+ return FALSE;
+}
-/*\r
- * Copyright (c) 2001, Gary R. Van Sickle.\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * A copy of the GNU General Public License can be found at\r
- * http://www.gnu.org/\r
- *\r
- * Written by Gary R. Van Sickle <g.r.vansickle@worldnet.att.net>\r
- *\r
- */\r
-\r
-// This is the implementation of the PropSheet class. This class encapsulates\r
-// a Windows property sheet / wizard and interfaces with the PropertyPage class.\r
-// It's named PropSheet instead of PropertySheet because the latter conflicts with\r
-// the Windows function of the same name.\r
-\r
-#include "propsheet.h"\r
-#include "proppage.h"\r
-\r
-//#include <shlwapi.h>\r
-// ...but since there is no shlwapi.h in mingw yet:\r
-typedef struct _DllVersionInfo\r
-{\r
- DWORD cbSize;\r
- DWORD dwMajorVersion;\r
- DWORD dwMinorVersion;\r
- DWORD dwBuildNumber;\r
- DWORD dwPlatformID;\r
-}\r
-DLLVERSIONINFO;\r
-typedef HRESULT CALLBACK (*DLLGETVERSIONPROC) (DLLVERSIONINFO * pdvi);\r
-#define PROPSHEETHEADER_V1_SIZE 40\r
-\r
-\r
-\r
-PropSheet::PropSheet ()\r
-{\r
- NumPropPages = 0;\r
-}\r
-\r
-PropSheet::~PropSheet ()\r
-{\r
-}\r
-\r
-HPROPSHEETPAGE *\r
-PropSheet::CreatePages ()\r
-{\r
- HPROPSHEETPAGE *retarray;\r
-\r
- // Create the return array\r
- retarray = new HPROPSHEETPAGE[NumPropPages];\r
-\r
- // Create the pages with CreatePropertySheetPage().\r
- // We do it here rather than in the PropertyPages themselves\r
- // because, for reasons known only to Microsoft, these handles will be\r
- // destroyed by the property sheet before the PropertySheet() call returns,\r
- // at least if it's modal (don't know about modeless).\r
- int i;\r
- for (i = 0; i < NumPropPages; i++)\r
- {\r
- retarray[i] =\r
- CreatePropertySheetPage (PropertyPages[i]->GetPROPSHEETPAGEPtr ());\r
-\r
- // Set position info\r
- if (i == 0)\r
- {\r
- PropertyPages[i]->YouAreFirst ();\r
- }\r
- else if (i == NumPropPages - 1)\r
- {\r
- PropertyPages[i]->YouAreLast ();\r
- }\r
- else\r
- {\r
- PropertyPages[i]->YouAreMiddle ();\r
- }\r
- }\r
-\r
- return retarray;\r
-}\r
-\r
-static DWORD\r
-GetPROPSHEETHEADERSize ()\r
-{\r
- // For compatibility with all versions of comctl32.dll, we have to do this.\r
-\r
- DLLVERSIONINFO vi;\r
- HMODULE mod;\r
- DLLGETVERSIONPROC DllGetVersion;\r
- DWORD retval = 0;\r
-\r
-\r
- // This 'isn't safe' in a DLL, according to MSDN\r
- mod = LoadLibrary ("comctl32.dll");\r
-\r
- DllGetVersion = (DLLGETVERSIONPROC) GetProcAddress (mod, "DllGetVersion");\r
- if (DllGetVersion == NULL)\r
- {\r
- // Something's wildly broken, punt.\r
- retval = PROPSHEETHEADER_V1_SIZE;\r
- }\r
- else\r
- {\r
- vi.cbSize = sizeof (DLLVERSIONINFO);\r
- DllGetVersion (&vi);\r
-\r
- if ((vi.dwMajorVersion < 4) ||\r
- ((vi.dwMajorVersion == 4) && (vi.dwMinorVersion < 71)))\r
- {\r
- // Recent.\r
- retval = sizeof (PROPSHEETHEADER);\r
- }\r
- else\r
- {\r
- // Old (== Win95/NT4 w/o IE 4 or better)\r
- retval = PROPSHEETHEADER_V1_SIZE;\r
- }\r
- }\r
-\r
- FreeLibrary (mod);\r
-\r
- return retval;\r
-}\r
-\r
-bool\r
-PropSheet::Create (const Window * Parent, DWORD Style)\r
-{\r
- PROPSHEETHEADER p;\r
-\r
- PageHandles = CreatePages ();\r
-\r
- p.dwSize = GetPROPSHEETHEADERSize ();\r
- p.dwFlags = PSH_NOAPPLYNOW | PSH_WIZARD /*| PSH_MODELESS */ ;\r
- if (Parent != NULL)\r
- {\r
- p.hwndParent = Parent->GetHWND ();\r
- }\r
- else\r
- {\r
- p.hwndParent = NULL;\r
- }\r
- p.hInstance = GetInstance ();\r
- p.nPages = NumPropPages;\r
- p.nStartPage = 0;\r
- p.phpage = PageHandles;\r
- p.pfnCallback = NULL;\r
-\r
-\r
- PropertySheet (&p);\r
-\r
- // Do a modeless property sheet...\r
- //SetHWND((HWND)PropertySheet(&p));\r
- /*Show(SW_SHOWNORMAL);\r
-\r
- // ...but pretend it's modal\r
- MessageLoop();\r
- MessageBox(NULL, "DONE", NULL, MB_OK);\r
-\r
- // FIXME: Enable the parent before destroying this window to prevent another window\r
- // from becoming the foreground window\r
- // ala: EnableWindow(<parent_hwnd>, TRUE);\r
- //DestroyWindow(WindowHandle);\r
- */\r
- SetHWND (NULL);\r
-\r
-\r
- return true;\r
-}\r
-\r
-void\r
-PropSheet::SetHWNDFromPage (HWND h)\r
-{\r
- // If we're a modal dialog, there's no way for us to know our window handle unless\r
- // one of our pages tells us through this function.\r
- SetHWND (h);\r
-}\r
-\r
-void\r
-PropSheet::AddPage (PropertyPage * p)\r
-{\r
- // Add a page to the property sheet.\r
- p->YouAreBeingAddedToASheet (this);\r
- PropertyPages[NumPropPages] = p;\r
- NumPropPages++;\r
-}\r
-\r
-bool\r
-PropSheet::SetActivePage (int i)\r
-{\r
- // Posts a message to the message queue, so this won't block\r
- return static_cast < bool > (::PropSheet_SetCurSel (GetHWND (), NULL, i));\r
-}\r
-\r
-bool\r
-PropSheet::SetActivePageByID (int resource_id)\r
-{\r
- // Posts a message to the message queue, so this won't block\r
- return static_cast < bool >\r
- (::PropSheet_SetCurSelByID (GetHWND (), resource_id));\r
-}\r
-\r
-void\r
-PropSheet::SetButtons (DWORD flags)\r
-{\r
- // Posts a message to the message queue, so this won't block\r
- ::PropSheet_SetWizButtons (GetHWND (), flags);\r
-}\r
-\r
-void\r
-PropSheet::PressButton (int button)\r
-{\r
- ::PropSheet_PressButton (GetHWND (), button);\r
-}\r
+/*
+ * Copyright (c) 2001, Gary R. Van Sickle.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * A copy of the GNU General Public License can be found at
+ * http://www.gnu.org/
+ *
+ * Written by Gary R. Van Sickle <g.r.vansickle@worldnet.att.net>
+ *
+ */
+
+// This is the implementation of the PropSheet class. This class encapsulates
+// a Windows property sheet / wizard and interfaces with the PropertyPage class.
+// It's named PropSheet instead of PropertySheet because the latter conflicts with
+// the Windows function of the same name.
+
+#include "propsheet.h"
+#include "proppage.h"
+
+//#include <shlwapi.h>
+// ...but since there is no shlwapi.h in mingw yet:
+typedef struct _DllVersionInfo
+{
+ DWORD cbSize;
+ DWORD dwMajorVersion;
+ DWORD dwMinorVersion;
+ DWORD dwBuildNumber;
+ DWORD dwPlatformID;
+}
+DLLVERSIONINFO;
+typedef HRESULT CALLBACK (*DLLGETVERSIONPROC) (DLLVERSIONINFO * pdvi);
+#define PROPSHEETHEADER_V1_SIZE 40
+
+
+
+PropSheet::PropSheet ()
+{
+ NumPropPages = 0;
+}
+
+PropSheet::~PropSheet ()
+{
+}
+
+HPROPSHEETPAGE *
+PropSheet::CreatePages ()
+{
+ HPROPSHEETPAGE *retarray;
+
+ // Create the return array
+ retarray = new HPROPSHEETPAGE[NumPropPages];
+
+ // Create the pages with CreatePropertySheetPage().
+ // We do it here rather than in the PropertyPages themselves
+ // because, for reasons known only to Microsoft, these handles will be
+ // destroyed by the property sheet before the PropertySheet() call returns,
+ // at least if it's modal (don't know about modeless).
+ int i;
+ for (i = 0; i < NumPropPages; i++)
+ {
+ retarray[i] =
+ CreatePropertySheetPage (PropertyPages[i]->GetPROPSHEETPAGEPtr ());
+
+ // Set position info
+ if (i == 0)
+ {
+ PropertyPages[i]->YouAreFirst ();
+ }
+ else if (i == NumPropPages - 1)
+ {
+ PropertyPages[i]->YouAreLast ();
+ }
+ else
+ {
+ PropertyPages[i]->YouAreMiddle ();
+ }
+ }
+
+ return retarray;
+}
+
+static DWORD
+GetPROPSHEETHEADERSize ()
+{
+ // For compatibility with all versions of comctl32.dll, we have to do this.
+
+ DLLVERSIONINFO vi;
+ HMODULE mod;
+ DLLGETVERSIONPROC DllGetVersion;
+ DWORD retval = 0;
+
+
+ // This 'isn't safe' in a DLL, according to MSDN
+ mod = LoadLibrary ("comctl32.dll");
+
+ DllGetVersion = (DLLGETVERSIONPROC) GetProcAddress (mod, "DllGetVersion");
+ if (DllGetVersion == NULL)
+ {
+ // Something's wildly broken, punt.
+ retval = PROPSHEETHEADER_V1_SIZE;
+ }
+ else
+ {
+ vi.cbSize = sizeof (DLLVERSIONINFO);
+ DllGetVersion (&vi);
+
+ if ((vi.dwMajorVersion < 4) ||
+ ((vi.dwMajorVersion == 4) && (vi.dwMinorVersion < 71)))
+ {
+ // Recent.
+ retval = sizeof (PROPSHEETHEADER);
+ }
+ else
+ {
+ // Old (== Win95/NT4 w/o IE 4 or better)
+ retval = PROPSHEETHEADER_V1_SIZE;
+ }
+ }
+
+ FreeLibrary (mod);
+
+ return retval;
+}
+
+bool PropSheet::Create (const Window * Parent, DWORD Style)
+{
+ PROPSHEETHEADER
+ p;
+
+ PageHandles = CreatePages ();
+
+ p.dwSize = GetPROPSHEETHEADERSize ();
+ p.dwFlags = PSH_NOAPPLYNOW | PSH_WIZARD /*| PSH_MODELESS */ ;
+ if (Parent != NULL)
+ {
+ p.hwndParent = Parent->GetHWND ();
+ }
+ else
+ {
+ p.hwndParent = NULL;
+ }
+ p.hInstance = GetInstance ();
+ p.nPages = NumPropPages;
+ p.nStartPage = 0;
+ p.phpage = PageHandles;
+ p.pfnCallback = NULL;
+
+
+ PropertySheet (&p);
+
+ // Do a modeless property sheet...
+ //SetHWND((HWND)PropertySheet(&p));
+ /*Show(SW_SHOWNORMAL);
+
+ // ...but pretend it's modal
+ MessageLoop();
+ MessageBox(NULL, "DONE", NULL, MB_OK);
+
+ // FIXME: Enable the parent before destroying this window to prevent another window
+ // from becoming the foreground window
+ // ala: EnableWindow(<parent_hwnd>, TRUE);
+ //DestroyWindow(WindowHandle);
+ */
+ SetHWND (NULL);
+
+
+ return true;
+}
+
+void
+PropSheet::SetHWNDFromPage (HWND h)
+{
+ // If we're a modal dialog, there's no way for us to know our window handle unless
+ // one of our pages tells us through this function.
+ SetHWND (h);
+}
+
+void
+PropSheet::AddPage (PropertyPage * p)
+{
+ // Add a page to the property sheet.
+ p->YouAreBeingAddedToASheet (this);
+ PropertyPages[NumPropPages] = p;
+ NumPropPages++;
+}
+
+bool PropSheet::SetActivePage (int i)
+{
+ // Posts a message to the message queue, so this won't block
+ return static_cast < bool > (::PropSheet_SetCurSel (GetHWND (), NULL, i));
+}
+
+bool PropSheet::SetActivePageByID (int resource_id)
+{
+ // Posts a message to the message queue, so this won't block
+ return static_cast < bool >
+ (::PropSheet_SetCurSelByID (GetHWND (), resource_id));
+}
+
+void
+PropSheet::SetButtons (DWORD flags)
+{
+ // Posts a message to the message queue, so this won't block
+ ::PropSheet_SetWizButtons (GetHWND (), flags);
+}
+
+void
+PropSheet::PressButton (int button)
+{
+ ::PropSheet_PressButton (GetHWND (), button);
+}
-/*\r
- * Copyright (c) 2001, Gary R. Van Sickle.\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * A copy of the GNU General Public License can be found at\r
- * http://www.gnu.org/\r
- *\r
- * Written by Gary R. Van Sickle <g.r.vansickle@worldnet.att.net>\r
- *\r
- */\r
-\r
-// This is the implementation of the Window class. It serves both as a window class\r
-// in its own right and as a base class for other window-like classes (e.g. PropertyPage,\r
-// PropSheet).\r
-\r
-#include <windows.h>\r
-#include "window.h"\r
-\r
-ATOM\r
- Window::WindowClassAtom =\r
- 0;\r
-HINSTANCE\r
- Window::AppInstance =\r
- NULL;\r
-\r
-// FIXME: I know, this is brutal. Mutexing should at least make window creation threadsafe,\r
-// but if somebody has any ideas as to how to get rid of it entirely, please tell me / do so.\r
-struct REFLECTION_INFO\r
-{\r
- Window *\r
- This;\r
- bool\r
- FirstCall;\r
-};\r
-REFLECTION_INFO\r
- ReflectionInfo;\r
-\r
-Window::Window ()\r
-{\r
- WindowHandle = NULL;\r
- Parent = NULL;\r
-}\r
-\r
-Window::~Window ()\r
-{\r
- // FIXME: Maybe do some reference counting and do this Unregister\r
- // when there are no more of us left. Not real critical unless\r
- // we're in a DLL which we're not right now.\r
- //UnregisterClass(WindowClassAtom, InstanceHandle);\r
-}\r
-\r
-LRESULT CALLBACK\r
-Window::FirstWindowProcReflector (HWND hwnd, UINT uMsg, WPARAM wParam,\r
- LPARAM lParam)\r
-{\r
- // Get our this pointer\r
- REFLECTION_INFO *rip = &ReflectionInfo;\r
-\r
- if (rip->FirstCall)\r
- {\r
- rip->FirstCall = false;\r
-\r
- // Set the Window handle so the real WindowProc has one to work with.\r
- rip->This->WindowHandle = hwnd;\r
-\r
- // Set a backreference to this class instance in the HWND.\r
- // FIXME: Should really be SetWindowLongPtr(), but it appears to\r
- // not be defined yet.\r
- SetWindowLong (hwnd, GWL_USERDATA, (LONG) rip->This);\r
-\r
- // Set a new WindowProc now that we have the peliminaries done.\r
- // Like subclassing, only not.\r
- SetWindowLong (hwnd, GWL_WNDPROC, (LONG) & Window::WindowProcReflector);\r
- }\r
-\r
- return rip->This->WindowProc (uMsg, wParam, lParam);\r
-}\r
-\r
-LRESULT CALLBACK\r
-Window::WindowProcReflector (HWND hwnd, UINT uMsg, WPARAM wParam,\r
- LPARAM lParam)\r
-{\r
- Window *This;\r
-\r
- // Get our this pointer\r
- // FIXME: Should really be GetWindowLongPtr(), but it appears to\r
- // not be defined yet.\r
- This = (Window *) GetWindowLong (hwnd, GWL_USERDATA);\r
-\r
- return This->WindowProc (uMsg, wParam, lParam);\r
-}\r
-\r
-bool\r
-Window::Create (Window * parent, DWORD Style)\r
-{\r
- // First register the window class, if we haven't already\r
- if (RegisterWindowClass () == false)\r
- {\r
- // Registration failed\r
- return false;\r
- }\r
-\r
- // Set up the reflection info, so that the Windows window can find us.\r
- ReflectionInfo.This = this;\r
- ReflectionInfo.FirstCall = true;\r
-\r
- Parent = parent;\r
-\r
- // Create the window instance\r
- WindowHandle = CreateWindow ("MainWindowClass", //MAKEINTATOM(WindowClassAtom), // window class atom (name)\r
- "Hello", // no title-bar string yet\r
- // Style bits\r
- Style,\r
- // Default positions and size\r
- CW_USEDEFAULT,\r
- CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,\r
- // Parent Window \r
- parent ==\r
- NULL ? (HWND) NULL : parent->GetHWND (),\r
- // use class menu \r
- (HMENU) NULL,\r
- // The application instance \r
- GetInstance (), (LPVOID) NULL);\r
-\r
- if (WindowHandle == NULL)\r
- {\r
- // Failed\r
- return false;\r
- }\r
-\r
- return true;\r
-}\r
-\r
-bool\r
-Window::RegisterWindowClass ()\r
-{\r
- if (WindowClassAtom == 0)\r
- {\r
- // We're not registered yet\r
- WNDCLASSEX wc;\r
-\r
- wc.cbSize = sizeof (wc);\r
- // Some sensible style defaults\r
- wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;\r
- // Our default window procedure. This replaces itself\r
- // on the first call with the simpler Window::WindowProcReflector().\r
- wc.lpfnWndProc = Window::FirstWindowProcReflector;\r
- // No class bytes\r
- wc.cbClsExtra = 0;\r
- // One pointer to REFLECTION_INFO in the extra window instance bytes\r
- wc.cbWndExtra = 4;\r
- // The app instance\r
- wc.hInstance = GetInstance ();\r
- // Use a bunch of system defaults for the GUI elements\r
- wc.hIcon = NULL;\r
- wc.hIconSm = NULL;\r
- wc.hCursor = NULL;\r
- wc.hbrBackground = (HBRUSH) (COLOR_BACKGROUND + 1);\r
- // No menu\r
- wc.lpszMenuName = NULL;\r
- // We'll get a little crazy here with the class name\r
- wc.lpszClassName = "MainWindowClass";\r
-\r
- // All set, try to register\r
- WindowClassAtom = RegisterClassEx (&wc);\r
-\r
- if (WindowClassAtom == 0)\r
- {\r
- // Failed\r
- return false;\r
- }\r
- }\r
-\r
- // We're registered, or already were before the call,\r
- // return success in either case.\r
- return true;\r
-}\r
-\r
-void\r
-Window::Show (int State)\r
-{\r
- ::ShowWindow (WindowHandle, State);\r
-}\r
-\r
-void\r
-Window::CenterWindow ()\r
-{\r
- RECT WindowRect, ParentRect;\r
- int WindowWidth, WindowHeight;\r
- POINT p;\r
-\r
- // Get the window rectangle\r
- GetWindowRect (GetHWND (), &WindowRect);\r
-\r
- if (GetParent () == NULL)\r
- {\r
- // Center on desktop window\r
- GetWindowRect (GetDesktopWindow (), &ParentRect);\r
- }\r
- else\r
- {\r
- // Center on client area of parent\r
- GetClientRect (GetParent ()->GetHWND (), &ParentRect);\r
- }\r
-\r
- WindowWidth = WindowRect.right - WindowRect.left;\r
- WindowHeight = WindowRect.bottom - WindowRect.top;\r
-\r
- // Find center of area we're centering on\r
- p.x = (ParentRect.right - ParentRect.left) / 2;\r
- p.y = (ParentRect.bottom - ParentRect.top) / 2;\r
-\r
- // Convert that to screen coords\r
- if (GetParent () == NULL)\r
- {\r
- ClientToScreen (GetDesktopWindow (), &p);\r
- }\r
- else\r
- {\r
- ClientToScreen (GetParent ()->GetHWND (), &p);\r
- }\r
-\r
- // Calculate new top left corner for window\r
- p.x -= WindowWidth / 2;\r
- p.y -= WindowHeight / 2;\r
-\r
- // And finally move the window\r
- MoveWindow (GetHWND (), p.x, p.y, WindowWidth, WindowHeight, TRUE);\r
-}\r
-\r
-LRESULT\r
-Window::WindowProc (UINT uMsg, WPARAM wParam, LPARAM lParam)\r
-{\r
- switch (uMsg)\r
- {\r
- default:\r
- return DefWindowProc (WindowHandle, uMsg, wParam, lParam);\r
- }\r
-\r
- return 0;\r
-}\r
-\r
-bool\r
-Window::MessageLoop ()\r
-{\r
- MSG msg;\r
-\r
- while (GetMessage (&msg, NULL, 0, 0) != 0\r
- && GetMessage (&msg, (HWND) NULL, 0, 0) != -1)\r
- {\r
- if (!IsWindow (WindowHandle) || !IsDialogMessage (WindowHandle, &msg))\r
- {\r
- TranslateMessage (&msg);\r
- DispatchMessage (&msg);\r
- }\r
- }\r
-\r
- return true;\r
-}\r
-\r
-void\r
-Window::PostMessage (UINT uMsg, WPARAM wParam, LPARAM lParam)\r
-{\r
- ::PostMessage (GetHWND (), uMsg, wParam, lParam);\r
-}\r
+/*
+ * Copyright (c) 2001, Gary R. Van Sickle.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * A copy of the GNU General Public License can be found at
+ * http://www.gnu.org/
+ *
+ * Written by Gary R. Van Sickle <g.r.vansickle@worldnet.att.net>
+ *
+ */
+
+// This is the implementation of the Window class. It serves both as a window class
+// in its own right and as a base class for other window-like classes (e.g. PropertyPage,
+// PropSheet).
+
+#include <windows.h>
+#include "window.h"
+
+ATOM Window::WindowClassAtom = 0;
+HINSTANCE Window::AppInstance = NULL;
+
+// FIXME: I know, this is brutal. Mutexing should at least make window creation threadsafe,
+// but if somebody has any ideas as to how to get rid of it entirely, please tell me / do so.
+struct REFLECTION_INFO
+{
+ Window *
+ This;
+ bool
+ FirstCall;
+};
+REFLECTION_INFO ReflectionInfo;
+
+Window::Window ()
+{
+ WindowHandle = NULL;
+ Parent = NULL;
+}
+
+Window::~Window ()
+{
+ // FIXME: Maybe do some reference counting and do this Unregister
+ // when there are no more of us left. Not real critical unless
+ // we're in a DLL which we're not right now.
+ //UnregisterClass(WindowClassAtom, InstanceHandle);
+}
+
+LRESULT CALLBACK
+Window::FirstWindowProcReflector (HWND hwnd, UINT uMsg, WPARAM wParam,
+ LPARAM lParam)
+{
+ // Get our this pointer
+ REFLECTION_INFO *rip = &ReflectionInfo;
+
+ if (rip->FirstCall)
+ {
+ rip->FirstCall = false;
+
+ // Set the Window handle so the real WindowProc has one to work with.
+ rip->This->WindowHandle = hwnd;
+
+ // Set a backreference to this class instance in the HWND.
+ // FIXME: Should really be SetWindowLongPtr(), but it appears to
+ // not be defined yet.
+ SetWindowLong (hwnd, GWL_USERDATA, (LONG) rip->This);
+
+ // Set a new WindowProc now that we have the peliminaries done.
+ // Like subclassing, only not.
+ SetWindowLong (hwnd, GWL_WNDPROC, (LONG) & Window::WindowProcReflector);
+ }
+
+ return rip->This->WindowProc (uMsg, wParam, lParam);
+}
+
+LRESULT CALLBACK
+Window::WindowProcReflector (HWND hwnd, UINT uMsg, WPARAM wParam,
+ LPARAM lParam)
+{
+ Window *This;
+
+ // Get our this pointer
+ // FIXME: Should really be GetWindowLongPtr(), but it appears to
+ // not be defined yet.
+ This = (Window *) GetWindowLong (hwnd, GWL_USERDATA);
+
+ return This->WindowProc (uMsg, wParam, lParam);
+}
+
+bool Window::Create (Window * parent, DWORD Style)
+{
+ // First register the window class, if we haven't already
+ if (RegisterWindowClass () == false)
+ {
+ // Registration failed
+ return false;
+ }
+
+ // Set up the reflection info, so that the Windows window can find us.
+ ReflectionInfo.This = this;
+ ReflectionInfo.FirstCall = true;
+
+ Parent = parent;
+
+ // Create the window instance
+ WindowHandle = CreateWindow ("MainWindowClass", //MAKEINTATOM(WindowClassAtom), // window class atom (name)
+ "Hello", // no title-bar string yet
+ // Style bits
+ Style,
+ // Default positions and size
+ CW_USEDEFAULT,
+ CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+ // Parent Window
+ parent ==
+ NULL ? (HWND) NULL : parent->GetHWND (),
+ // use class menu
+ (HMENU) NULL,
+ // The application instance
+ GetInstance (), (LPVOID) NULL);
+
+ if (WindowHandle == NULL)
+ {
+ // Failed
+ return false;
+ }
+
+ return true;
+}
+
+bool Window::RegisterWindowClass ()
+{
+ if (WindowClassAtom == 0)
+ {
+ // We're not registered yet
+ WNDCLASSEX
+ wc;
+
+ wc.cbSize = sizeof (wc);
+ // Some sensible style defaults
+ wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;
+ // Our default window procedure. This replaces itself
+ // on the first call with the simpler Window::WindowProcReflector().
+ wc.lpfnWndProc = Window::FirstWindowProcReflector;
+ // No class bytes
+ wc.cbClsExtra = 0;
+ // One pointer to REFLECTION_INFO in the extra window instance bytes
+ wc.cbWndExtra = 4;
+ // The app instance
+ wc.hInstance = GetInstance ();
+ // Use a bunch of system defaults for the GUI elements
+ wc.hIcon = NULL;
+ wc.hIconSm = NULL;
+ wc.hCursor = NULL;
+ wc.hbrBackground = (HBRUSH) (COLOR_BACKGROUND + 1);
+ // No menu
+ wc.lpszMenuName = NULL;
+ // We'll get a little crazy here with the class name
+ wc.lpszClassName = "MainWindowClass";
+
+ // All set, try to register
+ WindowClassAtom = RegisterClassEx (&wc);
+
+ if (WindowClassAtom == 0)
+ {
+ // Failed
+ return false;
+ }
+ }
+
+ // We're registered, or already were before the call,
+ // return success in either case.
+ return true;
+}
+
+void
+Window::Show (int State)
+{
+ ::ShowWindow (WindowHandle, State);
+}
+
+void
+Window::CenterWindow ()
+{
+ RECT WindowRect, ParentRect;
+ int WindowWidth, WindowHeight;
+ POINT p;
+
+ // Get the window rectangle
+ GetWindowRect (GetHWND (), &WindowRect);
+
+ if (GetParent () == NULL)
+ {
+ // Center on desktop window
+ GetWindowRect (GetDesktopWindow (), &ParentRect);
+ }
+ else
+ {
+ // Center on client area of parent
+ GetClientRect (GetParent ()->GetHWND (), &ParentRect);
+ }
+
+ WindowWidth = WindowRect.right - WindowRect.left;
+ WindowHeight = WindowRect.bottom - WindowRect.top;
+
+ // Find center of area we're centering on
+ p.x = (ParentRect.right - ParentRect.left) / 2;
+ p.y = (ParentRect.bottom - ParentRect.top) / 2;
+
+ // Convert that to screen coords
+ if (GetParent () == NULL)
+ {
+ ClientToScreen (GetDesktopWindow (), &p);
+ }
+ else
+ {
+ ClientToScreen (GetParent ()->GetHWND (), &p);
+ }
+
+ // Calculate new top left corner for window
+ p.x -= WindowWidth / 2;
+ p.y -= WindowHeight / 2;
+
+ // And finally move the window
+ MoveWindow (GetHWND (), p.x, p.y, WindowWidth, WindowHeight, TRUE);
+}
+
+LRESULT Window::WindowProc (UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ default:
+ return DefWindowProc (WindowHandle, uMsg, wParam, lParam);
+ }
+
+ return 0;
+}
+
+bool Window::MessageLoop ()
+{
+ MSG
+ msg;
+
+ while (GetMessage (&msg, NULL, 0, 0) != 0
+ && GetMessage (&msg, (HWND) NULL, 0, 0) != -1)
+ {
+ if (!IsWindow (WindowHandle) || !IsDialogMessage (WindowHandle, &msg))
+ {
+ TranslateMessage (&msg);
+ DispatchMessage (&msg);
+ }
+ }
+
+ return true;
+}
+
+void
+Window::PostMessage (UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ ::PostMessage (GetHWND (), uMsg, wParam, lParam);
+}
-#ifndef CINSTALL_WINDOW_H\r
-#define CINSTALL_WINDOW_H\r
-\r
-/*\r
- * Copyright (c) 2001, Gary R. Van Sickle.\r
- *\r
- * This program is free software; you can redistribute it and/or modify\r
- * it under the terms of the GNU General Public License as published by\r
- * the Free Software Foundation; either version 2 of the License, or\r
- * (at your option) any later version.\r
- *\r
- * A copy of the GNU General Public License can be found at\r
- * http://www.gnu.org/\r
- *\r
- * Written by Gary R. Van Sickle <g.r.vansickle@worldnet.att.net>\r
- *\r
- */\r
-\r
-// This is the header for the Window class. It serves both as a window class\r
-// in its own right and as a base class for other window-like classes (e.g. PropertyPage,\r
-// PropSheet).\r
-\r
-#include <windows.h>\r
-\r
-class Window\r
-{\r
- static ATOM WindowClassAtom;\r
- static HINSTANCE AppInstance;\r
-\r
-\r
- bool RegisterWindowClass ();\r
- static LRESULT CALLBACK FirstWindowProcReflector (HWND hwnd, UINT uMsg,\r
- WPARAM wParam,\r
- LPARAM lParam);\r
- static LRESULT CALLBACK WindowProcReflector (HWND hwnd, UINT uMsg,\r
- WPARAM wParam, LPARAM lParam);\r
-\r
- HWND WindowHandle;\r
-\r
- Window *Parent;\r
-\r
-protected:\r
- void SetHWND (HWND h)\r
- {\r
- WindowHandle = h;\r
- };\r
-\r
-public:\r
- Window ();\r
- virtual ~ Window ();\r
-\r
- static void SetAppInstance (HINSTANCE h)\r
- {\r
- AppInstance = h;\r
- };\r
-\r
- virtual LRESULT WindowProc (UINT uMsg, WPARAM wParam, LPARAM lParam);\r
- virtual bool MessageLoop ();\r
-\r
- virtual bool Create (Window * Parent = NULL,\r
- DWORD Style =\r
- WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN);\r
- void Show (int State);\r
-\r
- HWND GetHWND () const\r
- {\r
- return WindowHandle;\r
- };\r
- HINSTANCE GetInstance () const\r
- {\r
- return AppInstance;\r
- };\r
-\r
- Window *GetParent () const\r
- {\r
- return Parent;\r
- };\r
- HWND GetDlgItem (int id) const\r
- {\r
- return::GetDlgItem (GetHWND (), id);\r
- };\r
-\r
- void PostMessage (UINT uMsg, WPARAM wParam = 0, LPARAM lParam = 0);\r
-\r
- virtual bool OnMessageApp (UINT uMsg, WPARAM wParam, LPARAM lParam)\r
- {\r
- return false;\r
- };\r
-\r
- // Center the window on the parent, or on screen if no parent.\r
- void CenterWindow ();\r
-\r
-};\r
-\r
-#endif // CINSTALL_WINDOW_H\r
+#ifndef CINSTALL_WINDOW_H
+#define CINSTALL_WINDOW_H
+
+/*
+ * Copyright (c) 2001, Gary R. Van Sickle.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * A copy of the GNU General Public License can be found at
+ * http://www.gnu.org/
+ *
+ * Written by Gary R. Van Sickle <g.r.vansickle@worldnet.att.net>
+ *
+ */
+
+// This is the header for the Window class. It serves both as a window class
+// in its own right and as a base class for other window-like classes (e.g. PropertyPage,
+// PropSheet).
+
+#include <windows.h>
+
+class Window
+{
+ static ATOM WindowClassAtom;
+ static HINSTANCE AppInstance;
+
+
+ bool RegisterWindowClass ();
+ static LRESULT CALLBACK FirstWindowProcReflector (HWND hwnd, UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam);
+ static LRESULT CALLBACK WindowProcReflector (HWND hwnd, UINT uMsg,
+ WPARAM wParam, LPARAM lParam);
+
+ HWND WindowHandle;
+
+ Window *Parent;
+
+protected:
+ void SetHWND (HWND h)
+ {
+ WindowHandle = h;
+ };
+
+public:
+ Window ();
+ virtual ~ Window ();
+
+ static void SetAppInstance (HINSTANCE h)
+ {
+ AppInstance = h;
+ };
+
+ virtual LRESULT WindowProc (UINT uMsg, WPARAM wParam, LPARAM lParam);
+ virtual bool MessageLoop ();
+
+ virtual bool Create (Window * Parent = NULL,
+ DWORD Style =
+ WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN);
+ void Show (int State);
+
+ HWND GetHWND () const
+ {
+ return WindowHandle;
+ };
+ HINSTANCE GetInstance () const
+ {
+ return AppInstance;
+ };
+
+ Window *GetParent () const
+ {
+ return Parent;
+ };
+ HWND GetDlgItem (int id) const
+ {
+ return::GetDlgItem (GetHWND (), id);
+ };
+
+ void PostMessage (UINT uMsg, WPARAM wParam = 0, LPARAM lParam = 0);
+
+ virtual bool OnMessageApp (UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ return false;
+ };
+
+ // Center the window on the parent, or on screen if no parent.
+ void CenterWindow ();
+
+};
+
+#endif // CINSTALL_WINDOW_H