From df62e0238e9b9326befa62089bffcfadca2aae86 Mon Sep 17 00:00:00 2001 From: Robert Collins Date: Tue, 1 Jan 2002 12:32:37 +0000 Subject: [PATCH] 2002-01-01 Robert Collins * 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. --- ChangeLog | 22 ++ README | 5 +- choose.cc | 62 ++++-- io_stream.cc | 21 +- io_stream.h | 8 +- package_db.cc | 46 +++-- package_meta.cc | 2 +- package_meta.h | 3 +- proppage.cc | 448 ++++++++++++++++++++-------------------- propsheet.cc | 432 ++++++++++++++++++++------------------- window.cc | 531 ++++++++++++++++++++++++------------------------ window.h | 190 ++++++++--------- 12 files changed, 909 insertions(+), 861 deletions(-) diff --git a/ChangeLog b/ChangeLog index f7a94e54..bbd608b6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,25 @@ +2002-01-01 Robert Collins + + * 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 * Makefile.in (iniparse.o): Accommodate newer bisons. diff --git a/README b/README index c24b8ace..3520273f 100644 --- a/README +++ b/README @@ -3,7 +3,6 @@ net releases. 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" @@ -26,7 +25,6 @@ WISHLIST: * 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. @@ -61,3 +59,6 @@ recently completed 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 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) + diff --git a/choose.cc b/choose.cc index 245119af..f443a5ab 100644 --- a/choose.cc +++ b/choose.cc @@ -469,19 +469,37 @@ note_width (struct _header *hdrs, HDC dc, const char *string, int addend, 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 ()) @@ -494,7 +512,7 @@ default_trust (HWND h, trusts trust) { 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 @@ -516,6 +534,18 @@ default_trust (HWND h, trusts trust) 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 @@ -849,7 +879,7 @@ view::init_headers (HDC dc) /* 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) @@ -957,7 +987,7 @@ set_view_mode (HWND h, views mode) 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) @@ -967,7 +997,7 @@ set_view_mode (HWND h, views mode) } 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); @@ -1052,7 +1082,7 @@ create_listview (HWND dlg, RECT * r) 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); @@ -1071,7 +1101,7 @@ dialog_cmd (HWND h, int id, HWND hwndctl, UINT code) { 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); @@ -1080,7 +1110,7 @@ dialog_cmd (HWND h, int id, HWND hwndctl, UINT code) 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); @@ -1089,7 +1119,7 @@ dialog_cmd (HWND h, int id, HWND hwndctl, UINT code) 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); @@ -1297,7 +1327,7 @@ do_choose (HINSTANCE h, HWND owner) 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" }; diff --git a/io_stream.cc b/io_stream.cc index eff261a6..80f24a7f 100644 --- a/io_stream.cc +++ b/io_stream.cc @@ -170,21 +170,24 @@ io_stream::move_copy (const char *from, const char *to) 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: @@ -272,5 +275,3 @@ io_stream::~io_stream () log (LOG_TIMESTAMP, "io_stream::~io_stream called"); return; } - - diff --git a/io_stream.h b/io_stream.h index ba044bd2..9b376e1d 100644 --- a/io_stream.h +++ b/io_stream.h @@ -152,9 +152,11 @@ public: /* 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 *); }; diff --git a/package_db.cc b/package_db.cc index 04b46956..223c990c 100644 --- a/package_db.cc +++ b/package_db.cc @@ -42,7 +42,7 @@ static const char *cvsid = packagedb::packagedb () { - io_stream * db = 0; + io_stream *db = 0; if (!installeddbread) { /* no parameters. Read in the local installation database. */ @@ -131,22 +131,22 @@ packagedb::flush () 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; @@ -158,9 +158,15 @@ packagedb::flush () 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; diff --git a/package_meta.cc b/package_meta.cc index 94eb220d..dd795907 100644 --- a/package_meta.cc +++ b/package_meta.cc @@ -150,7 +150,7 @@ packagemeta::add_category (Category & cat) } char const * -packagemeta::SDesc () +packagemeta::SDesc () const { return versions[1]->SDesc (); }; diff --git a/package_meta.h b/package_meta.h index 49b336b5..fc7fe3a4 100644 --- a/package_meta.h +++ b/package_meta.h @@ -70,7 +70,6 @@ public: strcpy (installed_from, installedfrom); }; - ~packagemeta () { delete[] name; @@ -91,7 +90,7 @@ public: 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. */ diff --git a/proppage.cc b/proppage.cc index 40f40b9f..db18137d 100644 --- a/proppage.cc +++ b/proppage.cc @@ -1,226 +1,222 @@ -/* - * 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 - * - */ - -// 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; -} +/* + * 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 + * + */ + +// 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; +} diff --git a/propsheet.cc b/propsheet.cc index 398116ea..ca5da958 100644 --- a/propsheet.cc +++ b/propsheet.cc @@ -1,217 +1,215 @@ -/* - * 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 - * - */ - -// 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 -// ...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(, 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); -} +/* + * 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 + * + */ + +// 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 +// ...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(, 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); +} diff --git a/window.cc b/window.cc index 979c71dd..8eccbd1f 100644 --- a/window.cc +++ b/window.cc @@ -1,269 +1,262 @@ -/* - * 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 - * - */ - -// 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 -#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); -} +/* + * 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 + * + */ + +// 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 +#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); +} diff --git a/window.h b/window.h index e1d0e68a..2cb405b0 100644 --- a/window.h +++ b/window.h @@ -1,95 +1,95 @@ -#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 - * - */ - -// 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 - -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 +#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 + * + */ + +// 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 + +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 -- 2.43.5