// The wxWindow destructor will take care of deleting the submenus. wxMenu::~wxMenu() { // we should free Windows resources only if Windows doesn't do it for us // which happens if we're attached to a menubar or a submenu of another // menu if ( m_hMenu && !IsAttached() && !GetParent() ) { if ( !::DestroyMenu(GetHmenu()) ) { wxLogLastError(wxT("DestroyMenu")); } } #if wxUSE_ACCEL // delete accels WX_CLEAR_ARRAY(m_accels); #endif // wxUSE_ACCEL delete m_radioData; }
void wxMenuItem::Enable(bool enable) { if ( m_isEnabled == enable ) return; if ( m_parentMenu ) { long rc = EnableMenuItem(GetHMenuOf(m_parentMenu), GetMSWId(), MF_BYCOMMAND | (enable ? MF_ENABLED : MF_GRAYED)); if ( rc == -1 ) { wxLogLastError(wxT("EnableMenuItem")); } } wxMenuItemBase::Enable(enable); }
// This is used by wxProcess::Activate(). extern bool wxMSWActivatePID(long pid) { wxFindByPidParams params; params.pid = (DWORD)pid; if ( ::EnumWindows(wxEnumFindByPidProc, (LPARAM)¶ms) != 0 ) { // No windows corresponding to this PID were found. return false; } if ( !::BringWindowToTop(params.hwnd) ) { wxLogLastError(wxS("BringWindowToTop")); return false; } return true; }
bool wxSpinCtrl::Reparent(wxWindowBase *newParent) { // Reparenting both the updown control and its buddy does not seem to work: // they continue to be connected somehow, but visually there is no feedback // on the buddy edit control. To avoid this problem, we reparent the buddy // window normally, but we recreate the updown control and reassign its // buddy. if ( !wxWindowBase::Reparent(newParent) ) return false; newParent->GetChildren().DeleteObject(this); // preserve the old values const wxSize size = GetSize(); int value = GetValue(); const wxRect btnRect = wxRectFromRECT(wxGetWindowRect(GetHwnd())); // destroy the old spin button UnsubclassWin(); if ( !::DestroyWindow(GetHwnd()) ) { wxLogLastError(wxT("DestroyWindow")); } // create and initialize the new one if ( !wxSpinButton::Create(GetParent(), GetId(), btnRect.GetPosition(), btnRect.GetSize(), GetWindowStyle(), GetName()) ) return false; SetValue(value); SetRange(m_min, m_max); SetInitialSize(size); // associate it with the buddy control again ::SetParent(GetBuddyHwnd(), GetHwndOf(GetParent())); (void)::SendMessage(GetHwnd(), UDM_SETBUDDY, (WPARAM)GetBuddyHwnd(), 0); return true; }
wxGLContext::wxGLContext(wxGLCanvas *win, const wxGLContext* other) { if ( s_wglContextAttribs[0] == 0 ) // create legacy context { m_glContext = wglCreateContext(win->GetHDC()); wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGL context") ); } else // create a context using attributes { // We need to create a temporary context to get the // wglCreateContextAttribsARB function HGLRC tempContext = wglCreateContext(win->GetHDC()); wxCHECK_RET( tempContext, wxT("Couldn't create OpenGL context") ); wglMakeCurrent(win->GetHDC(), tempContext); PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC) wglGetProcAddress("wglCreateContextAttribsARB"); wglMakeCurrent(win->GetHDC(), NULL); wglDeleteContext(tempContext); if ( !wglCreateContextAttribsARB ) { wxLogError(_("Core OpenGL profile is not supported by the OpenGL driver.")); return; } m_glContext = wglCreateContextAttribsARB( win->GetHDC(), 0, s_wglContextAttribs); wxCHECK_RET( m_glContext, wxT("Couldn't create core profile OpenGL context") ); } if ( other ) { if ( !wglShareLists(other->m_glContext, m_glContext) ) { wxLogLastError(wxT("wglShareLists")); } } }
wxMenu* wxMenuBar::Replace( size_t nPos , wxMenu* pMenu , const wxString& rTitle ) { SHORT nId; wxString sTitle = wxPMTextToLabel(rTitle); wxMenu* pMenuOld = wxMenuBarBase::Replace( nPos ,pMenu ,sTitle ); nId = SHORT1FROMMR(::WinSendMsg((HWND)m_hMenu, MM_ITEMIDFROMPOSITION, MPFROMSHORT(nPos), (MPARAM)0)); if (nId == MIT_ERROR) { wxLogLastError(wxT("LogLastError")); return NULL; } if (!pMenuOld) return NULL; m_titles[nPos] = sTitle; if (IsAttached()) { ::WinSendMsg((HWND)m_hMenu, MM_REMOVEITEM, MPFROM2SHORT(nId, TRUE), (MPARAM)0); ::WinSendMsg((HWND)m_hMenu, MM_INSERTITEM, (MPARAM)&pMenu->m_vMenuData, (MPARAM)sTitle.wx_str()); #if wxUSE_ACCEL if (pMenuOld->HasAccels() || pMenu->HasAccels()) { // // Need to rebuild accell table // RebuildAccelTable(); } #endif // wxUSE_ACCEL Refresh(); } return pMenuOld; } // end of wxMenuBar::Replace
void wxMemoryDC::SelectObject(const wxBitmap& bitmap) { // select old bitmap out of the device context if ( m_oldBitmap ) { ::SelectObject(GetHdc(), (HBITMAP) m_oldBitmap); if ( m_selectedBitmap.Ok() ) { #ifdef __WXDEBUG__ m_selectedBitmap.SetSelectedInto(NULL); #endif m_selectedBitmap = wxNullBitmap; } } // check for whether the bitmap is already selected into a device context wxASSERT_MSG( !bitmap.GetSelectedInto() || (bitmap.GetSelectedInto() == this), wxT("Bitmap is selected in another wxMemoryDC, delete the first wxMemoryDC or use SelectObject(NULL)") ); m_selectedBitmap = bitmap; WXHBITMAP hBmp = m_selectedBitmap.GetHBITMAP(); if ( !hBmp ) return; #ifdef __WXDEBUG__ m_selectedBitmap.SetSelectedInto(this); #endif hBmp = (WXHBITMAP)::SelectObject(GetHdc(), (HBITMAP)hBmp); if ( !hBmp ) { wxLogLastError(wxT("SelectObject(memDC, bitmap)")); wxFAIL_MSG(wxT("Couldn't select a bitmap into wxMemoryDC")); } else if ( !m_oldBitmap ) { m_oldBitmap = hBmp; } }
void wxMenuItem::Enable(bool enable) { if ( m_isEnabled == enable ) return; const int itemPos = MSGetMenuItemPos(); if ( itemPos != -1 ) { long rc = EnableMenuItem(GetHMenuOf(m_parentMenu), itemPos, MF_BYPOSITION | (enable ? MF_ENABLED : MF_GRAYED)); if ( rc == -1 ) { wxLogLastError(wxT("EnableMenuItem")); } } wxMenuItemBase::Enable(enable); }
WXHBRUSH wxNotebook::MSWGetBgBrushForChild(WXHDC hDC, wxWindow *child) { if ( m_hbrBackground ) { // before drawing with the background brush, we need to position it // correctly RECT rc; ::GetWindowRect(GetHwndOf(child), &rc); ::MapWindowPoints(NULL, GetHwnd(), (POINT *)&rc, 1); if ( !::SetBrushOrgEx((HDC)hDC, -rc.left, -rc.top, NULL) ) { wxLogLastError(wxT("SetBrushOrgEx(notebook bg brush)")); } return m_hbrBackground; } return wxNotebookBase::MSWGetBgBrushForChild(hDC, child); }
// // The wxWindow destructor will take care of deleting the submenus. // wxMenu::~wxMenu() { // // We should free PM resources only if PM doesn't do it for us // which happens if we're attached to a menubar or a submenu of another // menu if (!IsAttached() && !GetParent()) { if (!::WinDestroyWindow((HWND)GetHmenu()) ) { wxLogLastError(wxT("WinDestroyWindow")); } } #if wxUSE_ACCEL // // Delete accels // WX_CLEAR_ARRAY(m_vAccels); #endif // wxUSE_ACCEL } // end of wxMenu::~wxMenu
wxString wxChoice::GetString(unsigned int n) const { int len = (int)::SendMessage(GetHwnd(), CB_GETLBTEXTLEN, n, 0); wxString str; if ( len != CB_ERR && len > 0 ) { if ( ::SendMessage ( GetHwnd(), CB_GETLBTEXT, n, (LPARAM)(wxChar *)wxStringBuffer(str, len) ) == CB_ERR ) { wxLogLastError(wxT("SendMessage(CB_GETLBTEXT)")); } } return str; }
wxSemaError wxSemaphoreInternal::Post() { #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 300) if ( !::ReleaseSemaphore(m_semaphore, 1, NULL /* ptr to previous count */) ) { if ( GetLastError() == ERROR_TOO_MANY_POSTS ) { return wxSEMA_OVERFLOW; } else { wxLogLastError(wxT("ReleaseSemaphore")); return wxSEMA_MISC_ERROR; } } return wxSEMA_NO_ERROR; #else return wxSEMA_MISC_ERROR; #endif }
bool gcTaskBarIcon::RemoveIcon() { #ifdef WIN32 if (!m_iconAdded) return false; m_iconAdded = false; NotifyIconData notifyData(GetHwndOf(m_win)); bool ok = wxShellNotifyIcon(NIM_DELETE, ¬ifyData) != 0; if ( !ok ) { wxLogLastError(wxT("wxShellNotifyIcon(NIM_DELETE)")); } return ok; #else return false; #endif }
bool wxMSWEventLoopBase::GetNextMessage(WXMSG* msg) { const BOOL rc = ::GetMessage(msg, NULL, 0, 0); if ( rc == 0 ) { // got WM_QUIT return false; } if ( rc == -1 ) { // should never happen, but let's test for it nevertheless wxLogLastError(wxT("GetMessage")); // still break from the loop return false; } return true; }
void wxApp::WakeUpIdle() { // // Send the top window a dummy message so idle handler processing will // start up again. Doing it this way ensures that the idle handler // wakes up in the right thread (see also wxWakeUpMainThread() which does // the same for the main app thread only) // wxWindow* pTopWindow = wxTheApp->GetTopWindow(); if (pTopWindow) { if ( !::WinPostMsg(GetHwndOf(pTopWindow), WM_NULL, (MPARAM)0, (MPARAM)0)) { // // Should never happen // wxLogLastError(wxT("PostMessage(WM_NULL)")); } } } // end of wxWakeUpIdle
// // NB: we don't support owner drawn top level items for now, if we do these // functions would have to be changed to use wxMenuItem as well // void wxMenuBar::EnableTop( size_t nPos , bool bEnable ) { wxCHECK_RET(IsAttached(), wxT("doesn't work with unattached menubars")); USHORT uFlag = 0; SHORT nId; if(!bEnable) uFlag = MIA_DISABLED; nId = SHORT1FROMMR(::WinSendMsg((HWND)m_hMenu, MM_ITEMIDFROMPOSITION, MPFROMSHORT(nPos), (MPARAM)0)); if (nId == MIT_ERROR) { wxLogLastError(wxT("LogLastError")); return; } ::WinSendMsg((HWND)m_hMenu, MM_SETITEMATTR, MPFROM2SHORT(nId, TRUE), MPFROM2SHORT(MIA_DISABLED, uFlag)); Refresh(); } // end of wxMenuBar::EnableTop
bool wxDIB::Create(HBITMAP hbmp) { // this bitmap could already be a DIB section in which case we don't need // to convert it to DIB DIBSECTION ds; if ( GetDIBSection(hbmp, &ds) ) { m_handle = hbmp; // wxBitmap will free it, not we m_ownsHandle = false; // copy all the bitmap parameters too as we have them now anyhow m_width = ds.dsBm.bmWidth; m_height = ds.dsBm.bmHeight; m_depth = ds.dsBm.bmBitsPixel; m_data = ds.dsBm.bmBits; } else // no, it's a DDB -- convert it to DIB { // prepare all the info we need BITMAP bm; if ( !::GetObject(hbmp, sizeof(bm), &bm) ) { wxLogLastError(wxT("GetObject(bitmap)")); return false; } int d = bm.bmBitsPixel; if ( d <= 0 ) d = wxDisplayDepth(); if ( !Create(bm.bmWidth, bm.bmHeight, d) || !CopyFromDDB(hbmp) ) return false; } return true; }
bool wxTextMeasure::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths, double scaleX) { if ( !m_hdc ) return wxTextMeasureBase::DoGetPartialTextExtents(text, widths, scaleX); static int maxLenText = -1; static int maxWidth = -1; if (maxLenText == -1) { // Win9x and WinNT+ have different limits int version = wxGetOsVersion(); maxLenText = version == wxOS_WINDOWS_NT ? 65535 : 8192; maxWidth = version == wxOS_WINDOWS_NT ? INT_MAX : 32767; } int len = text.length(); if ( len > maxLenText ) len = maxLenText; int fit = 0; SIZE sz = {0,0}; if ( !::GetTextExtentExPoint(m_hdc, text.t_str(), // string to check len, maxWidth, &fit, // [out] count of chars // that will fit &widths[0], // array to fill &sz) ) { wxLogLastError(wxT("GetTextExtentExPoint")); return false; } return true; }
bool wxTextMeasure::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths, double scaleX) { if ( !m_layout ) return wxTextMeasureBase::DoGetPartialTextExtents(text, widths, scaleX); // Set layout's text const wxCharBuffer dataUTF8 = wxGTK_CONV_FONT(text, GetFont()); if ( !dataUTF8 ) { // hardly ideal, but what else can we do if conversion failed? wxLogLastError(wxT("GetPartialTextExtents")); return false; } pango_layout_set_text(m_layout, dataUTF8, -1); // Calculate the position of each character based on the widths of // the previous characters // Code borrowed from Scintilla's PlatGTK PangoLayoutIter *iter = pango_layout_get_iter(m_layout); PangoRectangle pos; pango_layout_iter_get_cluster_extents(iter, NULL, &pos); size_t i = 0; while (pango_layout_iter_next_cluster(iter)) { pango_layout_iter_get_cluster_extents(iter, NULL, &pos); int position = PANGO_PIXELS(pos.x); widths[i++] = position; } const size_t len = text.length(); while (i < len) widths[i++] = PANGO_PIXELS(pos.x + pos.width); pango_layout_iter_free(iter); return true; }
// End drag bool wxDragImage::EndDrag() { wxASSERT_MSG( (m_hImageList != 0), wxT("Image list must not be null in EndDrag.")); ImageList_EndDrag(); if ( !::ReleaseCapture() ) { wxLogLastError(wxT("ReleaseCapture")); } #if wxUSE_SIMPLER_DRAGIMAGE if (m_cursor.Ok() && m_oldCursor.Ok()) m_window->SetCursor(m_oldCursor); #else ::ShowCursor(TRUE); #endif m_window = NULL; return true; }
bool wxDoSetEnv(const wxString& var, const wxChar *value) { #ifdef __WXWINCE__ // no environment variables under CE wxUnusedVar(var); wxUnusedVar(value); return false; #else // !__WXWINCE__ // update the CRT environment if possible as people expect getenv() to also // work and it is not affected by Win32 SetEnvironmentVariable() call (OTOH // the CRT does use Win32 call to update the process environment block so // there is no need to call it) // // TODO: add checks for the other compilers (and update wxSetEnv() // documentation in interface/wx/utils.h accordingly) #if defined(__VISUALC__) || defined(__MINGW32__) // notice that Microsoft _putenv() has different semantics from POSIX // function with almost the same name: in particular it makes a copy of the // string instead of using it as part of environment so we can safely call // it here without going through all the troubles with wxSetEnvModule as in // src/unix/utilsunx.cpp wxString envstr = var; envstr += '='; if ( value ) envstr += value; if ( _tputenv(envstr.t_str()) != 0 ) return false; #else // other compiler if ( !::SetEnvironmentVariable(var.t_str(), value) ) { wxLogLastError(wxT("SetEnvironmentVariable")); return false; } #endif // compiler return true; #endif // __WXWINCE__/!__WXWINCE__ }
void wxStatusBar95::SetStatusText(const wxString& strText, int nField) { wxCHECK_RET( (nField >= 0) && (nField < m_nFields), _T("invalid statusbar field index") ); if ( strText == GetStatusText(nField) ) { // don't call StatusBar_SetText() to avoid flicker return; } // Get field style, if any int style; if (m_statusStyles) { switch(m_statusStyles[nField]) { case wxSB_RAISED: style = SBT_POPOUT; break; case wxSB_FLAT: style = SBT_NOBORDERS; break; case wxSB_NORMAL: default: style = 0; break; } } else style = 0; // Pass both field number and style. MSDN library doesn't mention // that nField and style have to be 'ORed' if ( !StatusBar_SetText(GetHwnd(), nField | style, strText) ) { wxLogLastError(wxT("StatusBar_SetText")); } }
wxSemaphoreInternal::wxSemaphoreInternal(int initialcount, int maxcount) { #if !defined(_WIN32_WCE) || (_WIN32_WCE >= 300) if ( maxcount == 0 ) { // make it practically infinite maxcount = INT_MAX; } m_semaphore = ::CreateSemaphore ( NULL, // default security attributes initialcount, maxcount, NULL // no name ); #endif if ( !m_semaphore ) { wxLogLastError(wxT("CreateSemaphore()")); } }
void wxTopLevelWindowMSW::DoGetPosition(int *x, int *y) const { if ( IsIconized() ) { WINDOWPLACEMENT wp; wp.length = sizeof(WINDOWPLACEMENT); if ( ::GetWindowPlacement(GetHwnd(), &wp) ) { RECT& rc = wp.rcNormalPosition; // the position returned by GetWindowPlacement() is in workspace // coordinates except for windows with WS_EX_TOOLWINDOW style if ( !HasFlag(wxFRAME_TOOL_WINDOW) ) { // we must use the correct display for the translation as the // task bar might be shown on one display but not the other one int n = wxDisplay::GetFromWindow(this); wxDisplay dpy(n == wxNOT_FOUND ? 0 : n); const wxPoint ptOfs = dpy.GetClientArea().GetPosition() - dpy.GetGeometry().GetPosition(); rc.left += ptOfs.x; rc.top += ptOfs.y; } if ( x ) *x = rc.left; if ( y ) *y = rc.top; return; } wxLogLastError(wxT("GetWindowPlacement")); } //else: normal case wxTopLevelWindowBase::DoGetPosition(x, y); }
// Operations bool gcTaskBarIcon::SetIcon(const wxIcon& icon, const wxString& tooltip) { #ifdef WIN32 m_icon = icon; m_strTooltip = tooltip; NotifyIconData notifyData(GetHwndOf(m_win)); if (icon.Ok()) { notifyData.uFlags |= NIF_ICON; notifyData.hIcon = GetHiconOf(icon); } // set NIF_TIP even for an empty tooltip: otherwise it would be impossible // to remove an existing tooltip using this function notifyData.uFlags |= NIF_TIP; if ( !tooltip.empty() ) { wxStrlcpy(notifyData.szTip, tooltip.wx_str(), WXSIZEOF(notifyData.szTip)); } bool ok = wxShellNotifyIcon(m_iconAdded ? NIM_MODIFY : NIM_ADD, ¬ifyData) != 0; if ( !ok ) { wxLogLastError(wxT("wxShellNotifyIcon(NIM_MODIFY/ADD)")); } if ( !m_iconAdded && ok ) m_iconAdded = true; return ok; #else return wxTaskBarIcon::SetIcon(icon, tooltip); #endif }
static void InsertWindowMenu(wxWindow *win, WXHMENU menu, HMENU subMenu) { // Try to insert Window menu in front of Help, otherwise append it. HMENU hmenu = (HMENU)menu; if (subMenu) { int N = GetMenuItemCount(hmenu); bool success = false; for ( int i = 0; i < N; i++ ) { wxChar buf[256]; int chars = GetMenuString(hmenu, i, buf, WXSIZEOF(buf), MF_BYPOSITION); if ( chars == 0 ) { wxLogLastError(wxT("GetMenuString")); continue; } if ( wxStripMenuCodes(wxString(buf)).IsSameAs(_("Help")) ) { success = true; ::InsertMenu(hmenu, i, MF_BYPOSITION | MF_POPUP | MF_STRING, (UINT)subMenu, _("&Window")); break; } } if ( !success ) { ::AppendMenu(hmenu, MF_POPUP, (UINT)subMenu, _("&Window")); } } MDISetMenu(win, hmenu, subMenu); }
HBITMAP wxDIB::CreateDDB(HDC hdc) const { wxCHECK_MSG( m_handle, 0, wxT("wxDIB::CreateDDB(): invalid object") ); DIBSECTION ds; if ( !GetDIBSection(m_handle, &ds) ) { wxLogLastError(wxT("GetObject(hDIB)")); return 0; } // how many colours are we going to have in the palette? DWORD biClrUsed = ds.dsBmih.biClrUsed; if ( !biClrUsed ) { // biClrUsed field might not be set biClrUsed = GetNumberOfColours(ds.dsBmih.biBitCount); } if ( !biClrUsed ) { return ConvertToBitmap((BITMAPINFO *)&ds.dsBmih, hdc, ds.dsBm.bmBits); } else { // fake a BITMAPINFO w/o bits, just the palette info wxCharBuffer bmi(sizeof(BITMAPINFO) + (biClrUsed - 1)*sizeof(RGBQUAD)); BITMAPINFO *pBmi = (BITMAPINFO *)bmi.data(); MemoryHDC hDC; // get the colour table SelectInHDC sDC(hDC, m_handle); ::GetDIBColorTable(hDC, 0, biClrUsed, pBmi->bmiColors); memcpy(&pBmi->bmiHeader, &ds.dsBmih, ds.dsBmih.biSize); return ConvertToBitmap(pBmi, hdc, ds.dsBm.bmBits); } }
// Gets an HDC for the specified printer configuration WXHDC WXDLLEXPORT wxGetPrinterDC(const wxPrintData& printDataConst) { #if wxUSE_PS_PRINTING // TODO wxUnusedVar(printDataConst); return 0; #else // native Windows printing wxWindowsPrintNativeData *data = (wxWindowsPrintNativeData *) printDataConst.GetNativeData(); data->TransferFrom( printDataConst ); wxString deviceName = printDataConst.GetPrinterName(); if ( deviceName.empty() ) { // Retrieve the default device name wxString portName; if ( !wxGetDefaultDeviceName(deviceName, portName) ) { return 0; // Could not get default device name } } HGLOBAL hDevMode = (HGLOBAL)(DWORD) data->GetDevMode(); DEVMODE *lpDevMode = hDevMode ? (DEVMODE *)::GlobalLock(hDevMode) : NULL; HDC hDC = ::CreateDC(NULL, deviceName, NULL, lpDevMode); if ( !hDC ) wxLogLastError(_T("CreateDC(printer)")); if ( lpDevMode ) ::GlobalUnlock(hDevMode); return (WXHDC) hDC; #endif // PostScript/Windows printing }
bool wxBitmapDataObject2::SetData(size_t WXUNUSED(len), const void *pBuf) { HBITMAP hbmp = *(HBITMAP *)pBuf; BITMAP bmp; if ( !GetObject(hbmp, sizeof(BITMAP), &bmp) ) { wxLogLastError(wxT("GetObject(HBITMAP)")); } wxBitmap bitmap(bmp.bmWidth, bmp.bmHeight, bmp.bmPlanes); bitmap.SetHBITMAP((WXHBITMAP)hbmp); if ( !bitmap.IsOk() ) { wxFAIL_MSG(wxT("pasting/dropping invalid bitmap")); return false; } SetBitmap(bitmap); return true; }
void wxMenu::Init() { m_doBreak = false; m_startRadioGroup = -1; // create the menu m_macMenuId = s_macNextMenuId++; m_hMenu = UMANewMenu(m_macMenuId, m_title, wxFont::GetDefaultEncoding() ); if ( !m_hMenu ) { wxLogLastError(wxT("UMANewMenu failed")); } wxAssociateMenuWithMacMenu( (MenuRef)m_hMenu , this ) ; // if we have a title, insert it in the beginning of the menu if ( !m_title.empty() ) { Append(idMenuTitle, m_title) ; AppendSeparator() ; } }