misc.cxx
上传用户:hzhsqp
上传日期:2007-01-06
资源大小:1600k
文件大小:32k
- /*
- * misc.cxx
- *
- * Miscellaneous GUI class implementation.
- *
- * Portable Windows Library
- *
- * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- *
- * The Original Code is Portable Windows Library.
- *
- * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
- *
- * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
- * All Rights Reserved.
- *
- * Contributor(s): ______________________________________.
- *
- * $Log: misc.cxx,v $
- * Revision 1.66 2000/03/17 20:32:22 robertj
- * Fixed race conditions in mult-threaded windows (dialogs in particular)
- *
- * Revision 1.65 2000/03/04 07:50:05 robertj
- * Fixed problem with window not appearing when assert on GUI based win32 apps.
- *
- * Revision 1.64 1999/11/06 05:13:47 robertj
- * Fixed reporting of memory leak that isn't for debug/trace stream.
- *
- * Revision 1.63 1999/10/24 11:52:05 robertj
- * Fixed problems with creating/deleting dialogs from background threads.
- *
- * Revision 1.62 1999/08/17 03:46:42 robertj
- * Fixed usage of inlines in optimised version.
- *
- * Revision 1.61 1999/08/07 07:13:23 robertj
- * Fixed problems with "balloon help" text popup.
- *
- * Revision 1.60 1999/06/14 07:59:39 robertj
- * Enhanced tracing again to add options to trace output (timestamps etc).
- *
- * Revision 1.59 1999/02/22 10:11:06 robertj
- * Added trace stream output to debug output stream.
- *
- * Revision 1.58 1998/12/12 00:45:44 robertj
- * new directory structure
- *
- * Revision 1.57 1998/11/30 04:49:50 robertj
- * New directory structure
- *
- * Revision 1.56 1998/10/13 14:14:41 robertj
- * Complete rewrite of memory leak detection code.
- *
- * Revision 1.55 1998/09/24 03:42:53 robertj
- * Added open software license.
- *
- * Revision 1.54 1998/04/07 13:31:34 robertj
- * Changed startup code to support PApplication class.
- *
- * Revision 1.53 1998/03/09 01:34:53 robertj
- * Changed "system" font to not be the system font, WIn95 weirdness.
- *
- * Revision 1.52 1997/07/08 12:56:31 robertj
- * DLL support
- *
- * Revision 1.51 1997/04/27 05:50:34 robertj
- * DLL support.
- *
- * Revision 1.50 1996/10/31 12:39:57 robertj
- * Added RCS keywords.
- *
- */
- #include <pwlib.h>
- #include <ptlibdebstrm.h>
- #if !P_USE_INLINES
- #include <pwlibpwlib.inl>
- #endif
- #define new PNEW
- //
- // If we are building with Win95/NT4 headers, we need to declare
- // the multimonitor-related metrics ourselves.
- //
- #ifndef SM_CMONITORS
- #define SM_XVIRTUALSCREEN 76
- #define SM_YVIRTUALSCREEN 77
- #define SM_CXVIRTUALSCREEN 78
- #define SM_CYVIRTUALSCREEN 79
- #define SM_CMONITORS 80
- #define SM_SAMEDISPLAYFORMAT 81
- #endif
- ///////////////////////////////////////////////////////////////////////////////
- // PKeyCode
- PKeyCode::PKeyCode(BOOL mouseMessage, WPARAM wParam, int other)
- {
- if (mouseMessage) {
- value = (Value)other;
- modifiers = NoModifier;
- if ((wParam&MK_CONTROL) != 0)
- modifiers = (Modifiers)(modifiers|Control);
- if ((wParam&MK_SHIFT) != 0)
- modifiers = (Modifiers)(modifiers|Shift);
- if ((wParam&MK_LBUTTON) != 0)
- modifiers = (Modifiers)(modifiers|LeftMouseButton);
- if ((wParam&MK_RBUTTON) != 0)
- modifiers = (Modifiers)(modifiers|RightMouseButton);
- }
- else {
- static Value fromVK[] = {
- NullValue, LeftButton, RightButton, Cancel, MiddleButton, NullValue,
- NullValue, NullValue, BackSpace, Tab, NullValue, NullValue, Clear,
- Return, NullValue, NullValue, ShiftKey, ControlKey, Altkey, Oem1,
- CapsLockKey, NullValue, NullValue, NullValue, NullValue, NullValue,
- NullValue, Escape, NullValue, NullValue, NullValue, NullValue, Space,
- PageUp, PageDown, End, Home, Left, Up, Right, Down, Oem2, Oem3,
- Oem4, Oem5, Insert, Delete, Help, KB0, KB1, KB2, KB3, KB4,
- KB5, KB6, KB7, KB8, KB9, NullValue, NullValue, NullValue, NullValue,
- NullValue, NullValue, NullValue, A, B, C, D, E, F, G, H, I, J, K, L, M,
- N, O, P, Q, R, S, T, U, V, W, X, Y, Z, NullValue, NullValue, NullValue,
- NullValue, NullValue, KP0, KP1, KP2, KP3, KP4, KP5, KP6, KP7, KP8, KP9,
- Multiply, Add, Separator, Subtract, Decimal, Divide, F1, F2, F3, F4,
- F5, F6, F7, F8, F9, F10, F11, F12, F13, F14, F15, F16, F17, F18, F19,
- F20, F21, F22, F23, F24, NullValue, NullValue, NullValue, NullValue,
- NullValue, NullValue, NullValue, NullValue, Oem6, Oem7,
- NullValue, NullValue, NullValue, NullValue, NullValue, NullValue, //97
- NullValue, NullValue, NullValue, NullValue, NullValue, NullValue, //9E
- NullValue, NullValue, NullValue, NullValue, NullValue, NullValue, //A5
- NullValue, NullValue, NullValue, NullValue, NullValue, NullValue, //AB
- NullValue, NullValue, NullValue, NullValue, NullValue, NullValue, //B1
- NullValue, NullValue, NullValue, NullValue, NullValue, NullValue, //B8
- NullValue, Oem8, Oem10, Oem11, Oem12, Oem13, Oem14, Oem15,
- NullValue, NullValue, NullValue, NullValue, NullValue, NullValue, //C6
- NullValue, NullValue, NullValue, NullValue, NullValue, NullValue, //CC
- NullValue, NullValue, NullValue, NullValue, NullValue, NullValue, //D2
- NullValue, NullValue, NullValue, NullValue, NullValue, NullValue, //D8
- NullValue, NullValue, Oem16, Oem17, Oem18, Oem19, Oem20, Oem21, //E0
- Oem22, Oem23, Oem24, Oem25, NullValue, Oem26, NullValue, //E7
- NullValue, Oem27, Oem28, Oem29, Oem30, Oem31, Oem32, Oem33, Oem34, //F0
- Oem35, Oem36, Oem37, Oem38, Oem39
- };
- value = wParam < PARRAYSIZE(fromVK) ? fromVK[wParam] : NullValue;
- modifiers = NoModifier;
- }
- }
- WORD PKeyCode::VKCode()
- {
- static WORD toVK[LastCode] = {
- 0, VK_LBUTTON, VK_RBUTTON, VK_MBUTTON,
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
- 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_NUMPAD4,
- VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7, VK_NUMPAD8, VK_NUMPAD9,
- VK_ADD, VK_SUBTRACT, VK_MULTIPLY, VK_DIVIDE, VK_SEPARATOR, VK_DECIMAL,
- VK_F1, VK_F2, VK_F3, VK_F4, VK_F5, VK_F6, VK_F7, VK_F8,
- VK_F9, VK_F10, VK_F11, VK_F12, VK_F13, VK_F14, VK_F15, VK_F16,
- VK_F17, VK_F18, VK_F19, VK_F20, VK_F21, VK_F22, VK_F23, VK_F24,
- VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT, VK_PRIOR, VK_NEXT, VK_HOME, VK_END,
- VK_INSERT, VK_DELETE, VK_F20, VK_F21, VK_F22, VK_F23,
- VK_CLEAR, VK_CANCEL, VK_HELP, VK_F24,
- VK_BACK, VK_TAB, VK_RETURN, VK_ESCAPE, VK_SPACE,
- VK_CAPITAL, VK_SHIFT, VK_CONTROL, VK_MENU, VK_CONTROL, VK_MENU, VK_MENU,
- VK_PAUSE, VK_SELECT, 0x2a, VK_EXECUTE, VK_SNAPSHOT, VK_NUMLOCK, VK_SCROLL,
- 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
- 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe6, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee,
- 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5
- };
- PAssert(value < LastCode, "Bad key code");
- return toVK[value];
- }
- WORD PKeyCode::MouseModifiers()
- {
- WORD mm = 0;
- if (IsModifier(Control))
- mm |= MK_CONTROL;
- if (IsModifier(Shift))
- mm |= MK_SHIFT;
- if (IsModifier(LeftMouseButton))
- mm |= MK_LBUTTON;
- if (IsModifier(RightMouseButton))
- mm |= MK_RBUTTON;
- return mm;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // PResourceData
- PResourceData::PResourceData(const PString & resType, PRESOURCE_ID resID)
- {
- HINSTANCE hInst = PApplication::Current().GetInstance();
- HRSRC hRes = FindResource(hInst, MAKEINTRESOURCE(resID), resType);
- hResource = LoadResource(hInst, PAssertNULL(hRes));
- lpResource = (LPSTR)LockResource(PAssertNULL(hResource));
- reference->size = 0; //(PINDEX)GlobalSize(hResource);
- }
- void PResourceData::CopyContents(const PResourceData & res)
- {
- hResource = res.hResource;
- lpResource = res.lpResource;
- }
- PObject::Comparison PResourceData::Compare(const PObject & obj) const
- {
- PAssert(obj.IsDescendant(PResourceData::Class()), PInvalidCast);
- return hResource == ((const PResourceData &)obj).hResource
- ? EqualTo : GreaterThan;
- }
- BOOL PResourceData::SetSize(PINDEX)
- {
- return TRUE;
- }
- void PResourceData::DestroyContents()
- {
- if (hResource != NULL) {
- UnlockResource(hResource);
- FreeResource(hResource);
- hResource = NULL;
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // PResourceString
- void PResourceString::Construct(PRESOURCE_ID resID)
- {
- PINDEX sz = 100;
- do {
- sz *= 2;
- } while (LoadString(PApplication::Current().GetInstance(),
- resID, GetPointer(sz+1), sz) >= sz);
- MakeMinimumSize();
- }
- ///////////////////////////////////////////////////////////////////////////////
- // PCursor
- PCursor::PCursor(PRESOURCE_ID resID)
- {
- deleteCursor = FALSE;
- switch ((unsigned)resID) {
- case PSTD_ID_CURSOR_ARROW :
- hCursor = LoadCursor(NULL, IDC_ARROW);
- break;
- case PSTD_ID_CURSOR_IBEAM :
- hCursor = LoadCursor(NULL, IDC_IBEAM);
- break;
- case PSTD_ID_CURSOR_WAIT :
- hCursor = LoadCursor(NULL, IDC_WAIT);
- break;
- case PSTD_ID_CURSOR_CROSS :
- hCursor = LoadCursor(NULL, IDC_CROSS);
- break;
- case PSTD_ID_CURSOR_MOVELEFT :
- case PSTD_ID_CURSOR_MOVERIGHT :
- case PSTD_ID_CURSOR_LEFTRIGHT :
- hCursor = LoadCursor(NULL, IDC_SIZEWE);
- break;
- case PSTD_ID_CURSOR_MOVETOP :
- case PSTD_ID_CURSOR_MOVEBOTTOM :
- case PSTD_ID_CURSOR_UPDOWN :
- hCursor = LoadCursor(NULL, IDC_SIZENS);
- break;
- case PSTD_ID_CURSOR_MOVETOPRIGHT :
- case PSTD_ID_CURSOR_MOVEBOTLEFT :
- hCursor = LoadCursor(NULL, IDC_SIZENESW);
- break;
- case PSTD_ID_CURSOR_MOVETOPLEFT :
- case PSTD_ID_CURSOR_MOVEBOTRIGHT :
- hCursor = LoadCursor(NULL, IDC_SIZENWSE);
- break;
- default :
- hCursor = LoadCursor(PApplication::Current().GetInstance(),
- MAKEINTRESOURCE(resID));
- deleteCursor = TRUE;
- }
- PAssertOS(hCursor != NULL);
- }
- PObject::Comparison PCursor::Compare(const PObject & obj) const
- {
- PAssert(obj.IsDescendant(PCursor::Class()), PInvalidCast);
- return hCursor == ((const PCursor &)obj).hCursor ? EqualTo : GreaterThan;
- }
- static char * GetMaskBits(const PPixelImage & mask)
- {
- HBITMAP hMask = mask->GetHBITMAP(NULL);
- BITMAP bm;
- GetObject(hMask, sizeof(bm), (LPSTR)&bm);
- int bufSize = bm.bmHeight*bm.bmWidthBytes;
- char * bits = new char[bufSize];
- GetBitmapBits(hMask, bufSize, bits);
- DeleteObject(hMask);
- return bits;
- }
- PCursor::PCursor(const PPixelImage & andMask,
- const PPixelImage & xorMask, const PPoint & hotSpot)
- {
- PApplication & owner = PApplication::Current();
- PAssert(andMask->GetDepth() == 1 &&
- andMask->GetDimensions() == owner.GetCursorSize() &&
- xorMask->GetDepth() == 1 &&
- xorMask->GetDimensions() == owner.GetCursorSize(),
- "Incompatible images for cursor");
- PAssert((PDIMENSION)hotSpot.X() < andMask->Width() &&
- (PDIMENSION)hotSpot.Y() < andMask->Height(),
- "Bad hot spot for cursor");
- char * andMaskBits = GetMaskBits(andMask);
- char * xorMaskBits = GetMaskBits(xorMask);
- hCursor = CreateCursor(owner.GetInstance(),
- hotSpot.X(), hotSpot.Y(),
- andMask->Width(), andMask->Height(),
- andMaskBits, xorMaskBits);
- delete [] andMaskBits;
- delete [] xorMaskBits;
- deleteCursor = TRUE;
- PAssertOS(hCursor != NULL);
- }
- void PCursor::DestroyContents()
- {
- if (deleteCursor && hCursor != NULL) {
- PAssertOS(SetCursor(LoadCursor(NULL, IDC_ARROW)) != NULL);
- PAssertOS(DestroyCursor(hCursor));
- hCursor = NULL;
- }
- }
- void PCursor::CopyContents(const PCursor & curs)
- {
- hCursor = curs.hCursor;
- deleteCursor = curs.deleteCursor;
- }
- //////////////////////////////////////////////////////////////////////////////
- // PCaret
- void PCaret::DestroyContents()
- {
- Deactivate(activeWindow);
- }
- void PCaret::CopyContents(const PCaret & c)
- {
- caretSize = c.caretSize;
- activeWindow = c.activeWindow;
- }
- #if defined(_WIN32)
- #define PCaretAssertOS PAssertOS
- #else
- #define PCaretAssertOS
- #endif
- void PCaret::Activate(PInteractor * activator, BOOL display)
- {
- Deactivate(activeWindow);
- if (caretSize.Width() > 0 && caretSize.Height() > 0) {
- activeWindow = activator;
- PCaretAssertOS(CreateCaret(activator->GetHWND(),
- NULL, caretSize.Width(), caretSize.Height()));
- SetPosition(activator);
- if (display)
- Show(activator);
- }
- }
- void PCaret::Deactivate(PInteractor * activator)
- {
- if (activeWindow != NULL && activeWindow == activator) {
- PCaretAssertOS(DestroyCaret());
- activeWindow = NULL;
- }
- }
- void PCaret::Show(PInteractor * activator)
- {
- if (activeWindow != NULL && activeWindow == activator)
- PCaretAssertOS(ShowCaret(activator->GetHWND()));
- }
- void PCaret::Hide(PInteractor * activator)
- {
- if (activeWindow != NULL && activeWindow == activator)
- PCaretAssertOS(HideCaret(activator->GetHWND()));
- }
- void PCaret::SetPosition(PInteractor * activator)
- {
- if (activeWindow != NULL && activeWindow == activator) {
- PPoint pos = activator->GetCaretPos(PInteractor::PixelCoords);
- PCaretAssertOS(SetCaretPos(pos.X(), pos.Y()));
- }
- }
- void PCaret::SetDimensions(PDIMENSION dx, PDIMENSION dy)
- {
- caretSize.SetWidth(dx);
- caretSize.SetHeight(dy);
- if (activeWindow != NULL)
- Activate(activeWindow, FALSE);
- }
- ///////////////////////////////////////////////////////////////////////////////
- // PImgIcon
- PImgIcon::PImgIcon(PRESOURCE_ID resID)
- {
- hBitmap = LoadBitmap(PApplication::Current().GetInstance(), MAKEINTRESOURCE(resID));
- PAssert(hBitmap != NULL, "Could not load resource.");
- }
- PImgIcon::PImgIcon(PCanvas & canvas, const PPixelImage & pix)
- {
- hBitmap = pix->GetHBITMAP(canvas.GetHDC());
- PAssertOS(hBitmap != NULL);
- }
- PObject::Comparison PImgIcon::Compare(const PObject & obj) const
- {
- PAssert(obj.IsDescendant(PImgIcon::Class()), PInvalidCast);
- return hBitmap == ((const PImgIcon &)obj).hBitmap ? EqualTo : GreaterThan;
- }
- void PImgIcon::DestroyContents()
- {
- if (hBitmap != NULL) {
- PAssertOS(DeleteObject(hBitmap));
- hBitmap = NULL;
- }
- }
- PDim PImgIcon::GetDimensions() const
- {
- BITMAP bm;
- GetObject(hBitmap, sizeof(bm), (LPSTR)&bm);
- return PDim((PDIMENSION)bm.bmWidth, (PDIMENSION)bm.bmHeight);
- }
- ///////////////////////////////////////////////////////////////////////////////
- // PIcon
- PIcon::PIcon(PRESOURCE_ID resID)
- : PImgIcon((HBITMAP)NULL)
- {
- deleteIcon = FALSE;
- switch ((unsigned)resID) {
- case PSTD_ID_ICON_INFORMATION :
- hIcon = LoadIcon(NULL, IDI_ASTERISK);
- break;
- case PSTD_ID_ICON_QUESTION :
- hIcon = LoadIcon(NULL, IDI_QUESTION);
- break;
- case PSTD_ID_ICON_EXCLAMATION :
- hIcon = LoadIcon(NULL, IDI_EXCLAMATION);
- break;
- case PSTD_ID_ICON_STOPSIGN :
- hIcon = LoadIcon(NULL, IDI_HAND);
- break;
- case PSTD_ID_ICON_WINDOW :
- hIcon = LoadIcon(NULL, IDI_APPLICATION);
- break;
- default :
- hIcon = LoadIcon(PApplication::Current().GetInstance(), MAKEINTRESOURCE(resID));
- deleteIcon = TRUE;
- }
- PAssertNULL(hIcon);
- }
- PObject::Comparison PIcon::Compare(const PObject & obj) const
- {
- PAssert(obj.IsDescendant(PIcon::Class()), PInvalidCast);
- return hIcon == ((const PIcon &)obj).hIcon ? EqualTo : GreaterThan;
- }
- void PIcon::DestroyContents()
- {
- if (deleteIcon && hIcon != NULL) {
- DestroyIcon(hIcon);
- hIcon = NULL;
- }
- }
- void PIcon::CopyContents(const PIcon & icon)
- {
- deleteIcon = icon.deleteIcon;
- hIcon = icon.hIcon;
- }
- PDim PIcon::GetDimensions() const
- {
- return PDim((PDIMENSION)GetSystemMetrics(SM_CXICON),
- (PDIMENSION)GetSystemMetrics(SM_CYICON));
- }
- ///////////////////////////////////////////////////////////////////////////////
- // PClipboard
- PClipboard::PClipboard(const PInteractor * wnd)
- : owner(PAssertNULL(wnd))
- {
- opened = OpenClipboard(wnd->GetHWND());
- emptied = FALSE;
- }
- PClipboard::~PClipboard()
- {
- if (opened)
- PAssertOS(CloseClipboard());
- }
- BOOL PClipboard::HasFormat(Format fmt)
- {
- static const UINT PClipboardFormats[NumFormats] = {
- CF_TEXT, CF_BITMAP, CF_METAFILEPICT
- };
-
- return opened && IsClipboardFormatAvailable(PClipboardFormats[fmt]);
- }
- BOOL PClipboard::HasFormat(const PString & fmt)
- {
- return opened && IsClipboardFormatAvailable(RegisterClipboardFormat(fmt));
- }
- DWORD PClipboard::GetSize(const PString & fmt)
- {
- if (!opened)
- return 0;
- HANDLE h = GetClipboardData(RegisterClipboardFormat(fmt));
- return h != NULL ? GlobalSize(h) : 0;
- }
- BOOL PClipboard::GetData(const PString & fmt, void * data, DWORD max)
- {
- if (!opened)
- return FALSE;
- HANDLE h = GetClipboardData(RegisterClipboardFormat(fmt));
- if (h == NULL)
- return FALSE;
- DWORD size = GlobalSize(h);
- memcpy(data, GlobalLock(h), (size_t)min(max, size));
- GlobalUnlock(h);
- return size <= max;
- }
-
- BOOL PClipboard::SetData(const PString & fmt, const void * data, DWORD len)
- {
- if (!opened)
- return FALSE;
- if (!emptied) {
- EmptyClipboard();
- emptied = TRUE;
- }
-
- #if !defined(_WIN32)
- PAssert(len < 65536, PInvalidParameter);
- #endif
- HANDLE h = GlobalAlloc(GHND, len);
- memcpy(GlobalLock(h), data, (size_t)len);
- GlobalUnlock(h);
- return SetClipboardData(RegisterClipboardFormat(fmt), h) != NULL;
- }
- PString PClipboard::GetText()
- {
- PString str;
- HANDLE h = GetClipboardData(CF_TEXT);
- if (h != NULL) {
- DWORD size = GlobalSize(h);
- #if !defined(_WIN32)
- PAssert(size < 65536, PInvalidParameter);
- #endif
- lstrcpy(str.GetPointer((PINDEX)size), (LPSTR)GlobalLock(h));
- GlobalUnlock(h);
- }
- return str;
- }
- BOOL PClipboard::SetText(const PString & str)
- {
- if (!opened)
- return FALSE;
- if (!emptied) {
- EmptyClipboard();
- emptied = TRUE;
- }
-
- PString winstr = PMakeOEMText(str);
- HANDLE h = GlobalAlloc(GHND, winstr.GetLength()+1);
- lstrcpy((LPSTR)GlobalLock(h), winstr);
- GlobalUnlock(h);
- SetClipboardData(CF_TEXT, h);
- return TRUE;
- }
- PPixelImage PClipboard::GetPixels()
- {
- HANDLE h = GetClipboardData(CF_BITMAP);
- if (h != NULL)
- return PPixelBase::CreateBitmap((HBITMAP)h);
- return PPixelImage();
- }
- BOOL PClipboard::SetPixels(const PPixelImage & pix)
- {
- if (!opened)
- return FALSE;
- if (!emptied) {
- EmptyClipboard();
- emptied = TRUE;
- }
-
- PAssertOS(SetClipboardData(CF_BITMAP, pix->GetHBITMAP(NULL)) != NULL);
- return TRUE;
- }
- PPictImage PClipboard::GetPict()
- {
- PPictImage dwg;
- #if defined(_WIN32)
- HENHMETAFILE h = (HENHMETAFILE)GetClipboardData(CF_ENHMETAFILE);
- if (h != NULL)
- dwg = PPictImage(new PPictBase(h));
- #else
- HANDLE h = GetClipboardData(CF_METAFILEPICT);
- if (h != NULL) {
- LPMETAFILEPICT m = (LPMETAFILEPICT)GlobalLock(h);
- dwg = PPictImage(new PPictBase(m->hMF));
- GlobalUnlock(h);
- }
- #endif
- return dwg;
- }
- BOOL PClipboard::SetPict(const PPictImage & pic)
- {
- if (!opened)
- return FALSE;
- if (!emptied) {
- EmptyClipboard();
- emptied = TRUE;
- }
-
- #if defined(_WIN32)
- return SetClipboardData(CF_ENHMETAFILE, pic->GetMETAFILE()) != NULL;
- #else
- HANDLE h = GlobalAlloc(GHND, sizeof(METAFILEPICT));
- if (h == NULL)
- return FALSE;
- LPMETAFILEPICT m = (LPMETAFILEPICT)GlobalLock(h);
- m->hMF = pic->GetMETAFILE();
- GlobalUnlock(h);
- SetClipboardData(CF_METAFILEPICT, h);
- return TRUE;
- #endif
- }
- ///////////////////////////////////////////////////////////////////////////////
- // PApplication
- PApplication::PApplication(const char * manuf, const char * name,
- WORD major, WORD minor, CodeStatus stat, WORD build)
- : PProcess(manuf, name, major, minor, stat, build),
- systemFont("System", 12),
- balloonFont("MS Sans Serif", 8)
- {
- }
- BOOL PApplication::IsGUIProcess() const
- {
- return TRUE;
- }
- static PApplication * PApplicationInstance;
- LRESULT PEXPORTED WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- return PApplicationInstance->WndProc(hWnd,msg,wParam,lParam);
- }
- BOOL PEXPORTED DlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- return PApplicationInstance->DlgProc(hWnd,msg,wParam,lParam);
- }
- BOOL PEXPORTED FileDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- return PApplicationInstance->FileDlgProc(hWnd,msg,wParam,lParam);
- }
- BOOL PEXPORTED PrintDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- return PApplicationInstance->PrintDlgProc(hWnd, msg, wParam, lParam);
- }
- BOOL PEXPORTED FontDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- return PApplicationInstance->FontDlgProc(hWnd,msg,wParam,lParam);
- }
- BOOL PEXPORTED ColourDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- return PApplicationInstance->ColourDlgProc(hWnd, msg, wParam, lParam);
- }
- #define SET_DLG_PROC(proc)
- wndProcPtr[PApplication::proc##ProcType] = (WNDPROC)::proc##Proc
- int PApplication::_main(void * arg)
- {
- PApplicationInstance = this;
- hInstance = (HINSTANCE)arg;
- SET_DLG_PROC(Wnd);
- SET_DLG_PROC(Dlg);
- SET_DLG_PROC(FileDlg);
- SET_DLG_PROC(PrintDlg);
- SET_DLG_PROC(FontDlg);
- SET_DLG_PROC(ColourDlg);
- Construct();
- #if PMEMORY_CHECK
- PMemoryHeap::SetIgnoreAllocations(TRUE);
- #endif
- ostream * debugStream = new PDebugStream;
- PSetErrorStream(debugStream); // Use OutputDebugString() stream
- PTrace::SetStream(debugStream);
- #if PMEMORY_CHECK
- PMemoryHeap::SetIgnoreAllocations(FALSE);
- #endif
- blowUpTimeout = 1000;
- doubleClick = 250;
- mainWindow = NULL;
- receivedQuitMessage = FALSE;
- hAccelerator = NULL;
- mdiClient = NULL;
- defaultHelpFile = GetFile();
- defaultHelpFile.SetType(".hlp");
- HDC hDC = CreateCompatibleDC(NULL);
- primaryScreenSize.SetWidth(GetSystemMetrics(SM_CXSCREEN));
- primaryScreenSize.SetHeight(GetSystemMetrics(SM_CYSCREEN));
- screenRect.SetX(GetSystemMetrics(SM_XVIRTUALSCREEN));
- screenRect.SetY(GetSystemMetrics(SM_YVIRTUALSCREEN));
- screenRect.SetWidth(GetSystemMetrics(SM_CXVIRTUALSCREEN));
- screenRect.SetHeight(GetSystemMetrics(SM_CYVIRTUALSCREEN));
- if (screenRect.Width() == 0 || screenRect.Height() == 0)
- screenRect = primaryScreenSize;
- screenResImperial.SetWidth((PDIMENSION)GetDeviceCaps(hDC, LOGPIXELSX));
- screenResImperial.SetHeight((PDIMENSION)GetDeviceCaps(hDC, LOGPIXELSY));
- screenResMetric.SetWidth((PDIMENSION)(screenResImperial.Width()*394L/1000L));
- screenResMetric.SetHeight((PDIMENSION)(screenResImperial.Height()*394L/1000L));
- cursorSize.SetWidth((PDIMENSION)GetSystemMetrics(SM_CXCURSOR));
- cursorSize.SetHeight((PDIMENSION)GetSystemMetrics(SM_CYCURSOR));
- iconSize.SetWidth((PDIMENSION)GetSystemMetrics(SM_CXICON));
- iconSize.SetHeight((PDIMENSION)GetSystemMetrics(SM_CYICON));
- titledBorder.SetWidth((PDIMENSION)GetSystemMetrics(SM_CXFRAME));
- titledBorder.SetHeight((PDIMENSION)GetSystemMetrics(SM_CYFRAME));
- dlgBorder.SetWidth((PDIMENSION)GetSystemMetrics(SM_CXDLGFRAME));
- dlgBorder.SetHeight((PDIMENSION)GetSystemMetrics(SM_CYDLGFRAME));
- border.SetWidth((PDIMENSION)GetSystemMetrics(SM_CXBORDER));
- border.SetHeight((PDIMENSION)GetSystemMetrics(SM_CYBORDER));
- defMainWindow.SetWidth((PDIMENSION)CW_USEDEFAULT);
- defMainWindow.SetHeight((PDIMENSION)CW_USEDEFAULT);
- defTitledWindow.SetWidth((PDIMENSION)CW_USEDEFAULT);
- defTitledWindow.SetHeight((PDIMENSION)CW_USEDEFAULT);
- screenColours = GetDeviceCaps(hDC, NUMCOLORS);
- screenDepth = (PDIMENSION)(GetDeviceCaps(hDC, BITSPIXEL)*GetDeviceCaps(hDC, PLANES));
- heightTitle = (PDIMENSION)GetSystemMetrics(SM_CYCAPTION);
- heightMenu = (PDIMENSION)GetSystemMetrics(SM_CYMENU);
- heightHScroll = (PDIMENSION)GetSystemMetrics(SM_CYHSCROLL);
- widthVScroll = (PDIMENSION)GetSystemMetrics(SM_CXVSCROLL);
- dblClkRect.SetWidth((PDIMENSION)GetSystemMetrics(SM_CXDOUBLECLK));
- dblClkRect.SetHeight((PDIMENSION)GetSystemMetrics(SM_CYDOUBLECLK));
- dblClkRect.Offset(-GetSystemMetrics(SM_CXDOUBLECLK)/2,
- -GetSystemMetrics(SM_CYDOUBLECLK)/2);
- windowFg.FromSYSCOLOR(COLOR_WINDOWTEXT);
- windowBk.FromSYSCOLOR(COLOR_WINDOW);
- highlightFg.FromSYSCOLOR(COLOR_HIGHLIGHTTEXT);
- highlightBk.FromSYSCOLOR(COLOR_HIGHLIGHT);
- menuFg.FromSYSCOLOR(COLOR_MENUTEXT);
- menuBk.FromSYSCOLOR(COLOR_MENU);
- balloonFg = menuFg;
- balloonBk = menuBk;
- grayText.FromSYSCOLOR(COLOR_GRAYTEXT);
- buttonFg.FromSYSCOLOR(COLOR_BTNTEXT);
- buttonBk.FromSYSCOLOR(COLOR_BTNFACE);
- buttonLighting.FromSYSCOLOR(COLOR_BTNHIGHLIGHT);
- buttonShadow.FromSYSCOLOR(COLOR_BTNSHADOW);
- scrollBar.FromSYSCOLOR(COLOR_SCROLLBAR);
- activeTitleFg.FromSYSCOLOR(COLOR_CAPTIONTEXT);
- activeTitleBk.FromSYSCOLOR(COLOR_ACTIVECAPTION);
- inactiveTitleFg.FromSYSCOLOR(COLOR_INACTIVECAPTIONTEXT);
- inactiveTitleBk.FromSYSCOLOR(COLOR_INACTIVECAPTION);
- activeBorder.FromSYSCOLOR(COLOR_ACTIVEBORDER);
- inactiveBorder.FromSYSCOLOR(COLOR_INACTIVEBORDER);
- DeleteDC(hDC);
- systemFont = PRealFont((HFONT)GetStockObject(DEFAULT_GUI_FONT));
- createdWindows.DisallowDeleteObjects();
- nonModalDialogs.DisallowDeleteObjects();
- delayedCreateInteractors.DisallowDeleteObjects();
- #ifndef P_PLATFORM_HAS_THREADS
- timerWnd = CreateWindow("STATIC", "",
- WS_POPUP, 0, 0, 0, 0, NULL, NULL, hInstance, NULL);
- SetWindowLong(PAssertNULL(timerWnd),
- GWL_WNDPROC, (DWORD)wndProcPtr[WndProcType]);
- lastSetTimerTick = 1; // Needs to be non-zero
- #endif
- Main();
- return GetTerminationValue();
- }
- void PApplication::Main()
- {
- while (ProcessMessage()) {
- windowsMutex.Wait();
- if (!delayedCreateInteractors.IsEmpty()) {
- for (PINDEX i = 0; i < delayedCreateInteractors.GetSize(); i++)
- delayedCreateInteractors[i].CreateHWND();
- delayedCreateInteractors.RemoveAll();
- delayedCreateInteractorsDone.Signal();
- }
- windowsMutex.Signal();
- delayedCloseInteractors.RemoveAll();
- }
- }
-
- #ifndef P_PLATFORM_HAS_THREADS
- void PApplication::OperatingSystemYield()
- {
- // Assure other MS-Windows tasks gets some time as well
- MSG msg;
- UINT id = 0x7fff;
- while (PeekMessage(&msg, NULL, id, id, PM_NOREMOVE))
- id--;
- GetTimerList()->Process();
- }
- #endif
- BOOL PApplication::ProcessMessage()
- {
- if (receivedQuitMessage)
- return FALSE;
- MSG msg;
- receivedQuitMessage = GetMessage(&msg, NULL, 0, 0) == 0;
- if (receivedQuitMessage)
- return FALSE;
- windowsMutex.Wait();
- for (PINDEX i = 0; i < nonModalDialogs.GetSize(); i++) {
- if (IsDialogMessage(nonModalDialogs[i].GetHWND(), &msg)) {
- windowsMutex.Signal();
- PassMainLoop();
- return TRUE;
- }
- }
- windowsMutex.Signal();
- if (mdiClient != NULL && TranslateMDISysAccel(mdiClient, &msg)) {
- PassMainLoop();
- return TRUE;
- }
- if (hAccelerator != NULL &&
- TranslateAccelerator(mainWindow->GetHWND(), hAccelerator, &msg)) {
- PassMainLoop();
- return TRUE;
- }
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- PassMainLoop();
- return TRUE;
- }
- LRESULT PApplication::WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
- {
- LRESULT retval;
- #ifndef P_PLATFORM_HAS_THREADS
- if (hWnd == timerWnd)
- retval = DefWindowProc(hWnd, msg, wParam, lParam);
- else {
- #endif
- PInteractor * window = (PInteractor *)createdWindows.GetAt(HWNDKey(hWnd));
- if (window == NULL)
- retval = DefWindowProc(hWnd, msg, wParam, lParam);
- else {
- PInteractor::_WindowsMessage message;
- message.event = msg;
- message.wParam = wParam;
- message.lParam = lParam;
- message.lResult = 0;
- message.processed = TRUE;
- PInteractor::_WindowsMessage * oldMessage = window->_msg;
- window->_msg = &message;
- window->WndProc();
- window->_msg = oldMessage;
- retval = message.lResult;
- }
- #ifndef P_PLATFORM_HAS_THREADS
- }
- if (timerWnd != NULL &&
- lastSetTimerTick != 0 && lastSetTimerTick != (UINT)GetTickCount()) {
- lastSetTimerTick = 0; // Prevent recursive calls
- Yield(); // Do the multithreading
- long delay = GetTimerList()->Process().GetInterval();
- if (!IsOnlyThread())
- delay = PTimer::Resolution();
- else if (delay > 60000)
- delay = 60000;
- KillTimer(timerWnd, 1);
- PAssertOS(SetTimer(timerWnd, 1, (UINT)delay, NULL) != 0);
- // Not too often or it gets really slow
- lastSetTimerTick = (UINT)GetTickCount();
- if (lastSetTimerTick == 0)
- lastSetTimerTick++;
- }
- #endif
- return retval;
- }
- void PApplication::AddDialog(PInteractorLayout * pWnd)
- {
- windowsMutex.Wait();
- nonModalDialogs.Append(pWnd);
- windowsMutex.Signal();
- }
- void PApplication::RemoveDialog(PInteractorLayout * pWnd)
- {
- windowsMutex.Wait();
- if (nonModalDialogs.GetObjectsIndex(pWnd) != P_MAX_INDEX)
- nonModalDialogs.Remove(pWnd);
- windowsMutex.Signal();
- }
- static void DoHelp(PTopLevelWindow * wnd,
- const PFilePath & helpFile,
- UINT fuCmd, DWORD dwData)
- {
- PFilePath realHelpFile = helpFile;
- if (realHelpFile.GetType().IsEmpty())
- realHelpFile.SetType(".hlp");
- WinHelp(wnd->GetHWND(), realHelpFile, fuCmd, dwData);
- }
- void PApplication::Terminate()
- {
- #ifndef P_PLATFORM_HAS_THREADS
- KillTimer(timerWnd, 1);
- lastSetTimerTick = 0; // Prevent WndProc from doing anything with timers
- #endif
- if (mainWindow != NULL) {
- DoHelp(mainWindow, defaultHelpFile, HELP_QUIT, 0);
- DelayedCloseInteractor(mainWindow);
- mainWindow = NULL;
- }
- PostQuitMessage(0);
- }
- void PApplication::DoContextHelp(const PString & context,
- const PFilePath & file)
- {
- DoHelp(mainWindow, file, HELP_KEY, (DWORD)(const char *)context);
- }
- void PApplication::DoContextHelp(PINDEX context, const PFilePath & file)
- {
- switch ((unsigned)context) {
- case PSTD_ID_HELP_CONTENTS :
- DoHelp(mainWindow, file, HELP_CONTENTS, 0);
- break;
- case PSTD_ID_HELP_SEARCH :
- DoHelp(mainWindow, file, HELP_PARTIALKEY, (DWORD)"");
- break;
- case PSTD_ID_HELP_ON_HELP :
- DoHelp(mainWindow, file, HELP_HELPONHELP, 0);
- break;
- default :
- DoHelp(mainWindow, file, HELP_KEY, context);
- }
- }
- PString PMakeOEMText(const PString & txt)
- {
- PString s;
- PINDEX lastPos = 0;
- PINDEX searchPos = 0;
- PINDEX pos;
- while ((pos = txt.FindOneOf("rn", searchPos)) != P_MAX_INDEX) {
- if (txt[pos] == 'r' && txt[pos+1] == 'n')
- searchPos = pos + 2;
- else {
- if (pos > 0)
- s += txt(lastPos, pos-1);
- s += "rn";
- lastPos = pos + 1;
- searchPos = lastPos;
- }
- }
- return s + txt(lastPos, pos);
- }
- // End Of File ///////////////////////////////////////////////////////////////