]>
git.saurik.com Git - wxWidgets.git/blob - src/os2/toolbar.cpp
1 /////////////////////////////////////////////////////////////////////////////
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
19 #if wxUSE_TOOLBAR && wxUSE_TOOLBAR_NATIVE
20 #include "wx/toolbar.h"
23 #include "wx/os2/private.h"
25 #include "wx/app.h" // for GetComCtl32Version
27 // ----------------------------------------------------------------------------
29 // ----------------------------------------------------------------------------
31 // these standard constants are not always defined in compilers headers
35 #define TBSTYLE_LIST 0x1000
36 #define TBSTYLE_FLAT 0x0800
37 #define TBSTYLE_TRANSPARENT 0x8000
39 // use TBSTYLE_TRANSPARENT if you use TBSTYLE_FLAT
43 #define TB_SETSTYLE (WM_USER + 56)
44 #define TB_GETSTYLE (WM_USER + 57)
48 #define TB_HITTEST (WM_USER + 69)
51 // these values correspond to those used by comctl32.dll
52 #define DEFAULTBITMAPX 16
53 #define DEFAULTBITMAPY 15
54 #define DEFAULTBUTTONX 24
55 #define DEFAULTBUTTONY 24
56 #define DEFAULTBARHEIGHT 27
58 // ----------------------------------------------------------------------------
59 // private function prototypes
60 // ----------------------------------------------------------------------------
62 static void wxMapBitmap( HBITMAP hBitmap
67 // ----------------------------------------------------------------------------
69 // ----------------------------------------------------------------------------
71 IMPLEMENT_DYNAMIC_CLASS(wxToolBar
, wxControl
)
73 BEGIN_EVENT_TABLE(wxToolBar
, wxToolBarBase
)
74 EVT_MOUSE_EVENTS(wxToolBar::OnMouseEvent
)
75 EVT_SYS_COLOUR_CHANGED(wxToolBar::OnSysColourChanged
)
78 // ----------------------------------------------------------------------------
80 // ----------------------------------------------------------------------------
82 class wxToolBarTool
: public wxToolBarToolBase
85 inline wxToolBarTool( wxToolBar
* pTbar
87 ,const wxString
& rsLabel
88 ,const wxBitmap
& rBitmap1
89 ,const wxBitmap
& rBitmap2
91 ,wxObject
* pClientData
92 ,const wxString
& rShortHelpString
93 ,const wxString
& rLongHelpString
94 ) : wxToolBarToolBase( pTbar
108 inline wxToolBarTool( wxToolBar
* pTbar
110 ) : wxToolBarToolBase( pTbar
117 // set/get the number of separators which we use to cover the space used by
118 // a control in the toolbar
119 inline void SetSeparatorsCount(size_t nCount
) { m_nSepCount
= nCount
; }
120 inline size_t GetSeparatorsCount(void) const { return m_nSepCount
; }
127 // ============================================================================
129 // ============================================================================
131 // ----------------------------------------------------------------------------
133 // ----------------------------------------------------------------------------
135 wxToolBarToolBase
* wxToolBar::CreateTool(
137 , const wxString
& rsLabel
138 , const wxBitmap
& rBitmap1
139 , const wxBitmap
& rBitmap2
141 , wxObject
* pClientData
142 , const wxString
& rShortHelpString
143 , const wxString
& rLongHelpString
146 return(new wxToolBarTool( this
158 wxToolBarToolBase
* wxToolBar::CreateTool(
162 return(new wxToolBarTool( this
167 // ----------------------------------------------------------------------------
168 // wxToolBar construction
169 // ----------------------------------------------------------------------------
171 void wxToolBar::Init()
175 m_defaultWidth
= DEFAULTBITMAPX
;
176 m_defaultHeight
= DEFAULTBITMAPY
;
179 bool wxToolBar::Create(
182 , const wxPoint
& rPos
183 , const wxSize
& rSize
185 , const wxString
& rName
188 // common initialisation
189 if (!CreateControl( pParent
200 DWORD msflags
= 0; // WS_VISIBLE | WS_CHILD always included
204 if (lStyle & wxBORDER)
205 msflags |= WS_BORDER;
206 msflags |= TBSTYLE_TOOLTIPS;
208 if (style & wxTB_FLAT)
210 if (wxTheApp->GetComCtl32Version() > 400)
211 msflags |= TBSTYLE_FLAT;
214 // MSW-specific initialisation
215 if ( !wxControl::MSWCreateControl(TOOLBARCLASSNAME, msflags) )
218 // toolbar-specific post initialisation
219 ::SendMessage(GetHwnd(), TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
221 // set up the colors and fonts
222 wxRGBToColour(m_backgroundColour, GetSysColor(COLOR_BTNFACE));
223 m_foregroundColour = *wxBLACK;
225 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
236 height = m_defaultHeight;
242 SetSize(x, y, width, height);
247 wxToolBar::~wxToolBar()
251 ::GpiDeleteBitmap((HBITMAP
) m_hBitmap
);
255 // ----------------------------------------------------------------------------
256 // adding/removing tools
257 // ----------------------------------------------------------------------------
259 bool wxToolBar::DoInsertTool(
260 size_t WXUNUSED(nPos
)
261 , wxToolBarToolBase
* pTool
264 // nothing special to do here - we really create the toolbar buttons in
270 bool wxToolBar::DoDeleteTool(
272 , wxToolBarToolBase
* pTool
275 // normally, we only delete one button, but we use several separators to
276 // cover the space used by one control sometimes (with old comctl32.dll)
277 size_t nButtonsToDelete
= 1;
279 // get the size of the button we're going to delete
284 if ( !::SendMessage(GetHwnd(), TB_GETITEMRECT, pos, (LPARAM)&r) )
286 wxLogLastError(_T("TB_GETITEMRECT"));
289 int width = r.right - r.left;
291 if ( tool->IsControl() )
293 nButtonsToDelete = ((wxToolBarTool *)tool)->GetSeparatorsCount();
295 width *= nButtonsToDelete;
298 while ( nButtonsToDelete-- > 0 )
300 if ( !::SendMessage(GetHwnd(), TB_DELETEBUTTON, pos, 0) )
302 wxLogLastError("TB_DELETEBUTTON");
310 m_nButtons -= nButtonsToDelete;
312 // reposition all the controls after this button
313 wxToolBarToolsList::Node *node = m_tools.Item(pos);
314 for ( node = node->GetNext(); node; node = node->GetNext() )
316 wxToolBarToolBase *tool2 = node->GetData();
317 if ( tool2->IsControl() )
320 wxControl *control = tool2->GetControl();
321 control->GetPosition(&x, NULL);
322 control->Move(x - width, -1);
329 bool wxToolBar::Realize()
331 size_t nTools
= GetToolsCount();
339 bool bIsVertical
= (GetWindowStyle() & wxTB_VERTICAL
) != 0;
343 // First, add the bitmap: we use one bitmap for all toolbar buttons
344 // ----------------------------------------------------------------
346 // if we already have a bitmap, we'll replace the existing one - otherwise
347 // we'll install a new one
348 HBITMAP oldToolBarBitmap = (HBITMAP)m_hBitmap;
350 int totalBitmapWidth = (int)(m_defaultWidth * nTools);
351 int totalBitmapHeight = (int)m_defaultHeight;
353 // Create a bitmap for all the tool bitmaps
354 HBITMAP hBitmap = ::CreateCompatibleBitmap(ScreenHDC(),
359 wxLogLastError(_T("CreateCompatibleBitmap"));
364 m_hBitmap = (WXHBITMAP)hBitmap;
366 // Now blit all the tools onto this bitmap
367 HDC memoryDC = ::CreateCompatibleDC(NULL);
368 HBITMAP oldBitmap = (HBITMAP) ::SelectObject(memoryDC, hBitmap);
370 HDC memoryDC2 = ::CreateCompatibleDC(NULL);
372 // the button position
375 // the number of buttons (not separators)
378 wxToolBarToolsList::Node *node = m_tools.GetFirst();
381 wxToolBarToolBase *tool = node->GetData();
382 if ( tool->IsButton() )
384 HBITMAP hbmp = GetHbitmapOf(tool->GetBitmap1());
387 HBITMAP oldBitmap2 = (HBITMAP)::SelectObject(memoryDC2, hbmp);
388 if ( !BitBlt(memoryDC, x, 0, m_defaultWidth, m_defaultHeight,
389 memoryDC2, 0, 0, SRCCOPY) )
391 wxLogLastError("BitBlt");
394 ::SelectObject(memoryDC2, oldBitmap2);
398 wxFAIL_MSG( _T("invalid tool button bitmap") );
401 // still inc width and number of buttons because otherwise the
402 // subsequent buttons will all be shifted which is rather confusing
403 // (and like this you'd see immediately which bitmap was bad)
408 node = node->GetNext();
411 ::SelectObject(memoryDC, oldBitmap);
412 ::DeleteDC(memoryDC);
413 ::DeleteDC(memoryDC2);
415 // Map to system colours
416 wxMapBitmap(hBitmap, totalBitmapWidth, totalBitmapHeight);
418 if ( oldToolBarBitmap )
420 TBREPLACEBITMAP replaceBitmap;
421 replaceBitmap.hInstOld = NULL;
422 replaceBitmap.hInstNew = NULL;
423 replaceBitmap.nIDOld = (UINT) oldToolBarBitmap;
424 replaceBitmap.nIDNew = (UINT) hBitmap;
425 replaceBitmap.nButtons = nButtons;
426 if ( !::SendMessage(GetHwnd(), TB_REPLACEBITMAP,
427 0, (LPARAM) &replaceBitmap) )
429 wxFAIL_MSG(wxT("Could not add bitmap to toolbar"));
432 ::DeleteObject(oldToolBarBitmap);
434 // Now delete all the buttons
435 for ( size_t pos = 0; pos < m_nButtons; pos++ )
437 if ( !::SendMessage(GetHwnd(), TB_DELETEBUTTON, 0, 0) )
439 wxLogLastError("TB_DELETEBUTTON");
443 else // no old bitmap
445 TBADDBITMAP addBitmap;
447 addBitmap.nID = (UINT) hBitmap;
448 if ( ::SendMessage(GetHwnd(), TB_ADDBITMAP,
449 (WPARAM) nButtons, (LPARAM)&addBitmap) == -1 )
451 wxFAIL_MSG(wxT("Could not add bitmap to toolbar"));
455 // Next add the buttons and separators
456 // -----------------------------------
458 TBBUTTON *buttons = new TBBUTTON[nTools];
460 // this array will hold the indices of all controls in the toolbar
461 wxArrayInt controlIds;
466 for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
468 wxToolBarToolBase *tool = node->GetData();
470 // don't add separators to the vertical toolbar - looks ugly
471 if ( isVertical && tool->IsSeparator() )
474 TBBUTTON& button = buttons[i];
476 wxZeroMemory(button);
478 switch ( tool->GetStyle() )
480 case wxTOOL_STYLE_CONTROL:
481 button.idCommand = tool->GetId();
482 // fall through: create just a separator too
484 case wxTOOL_STYLE_SEPARATOR:
485 button.fsState = TBSTATE_ENABLED;
486 button.fsStyle = TBSTYLE_SEP;
489 case wxTOOL_STYLE_BUTTON:
490 button.iBitmap = bitmapId;
491 button.idCommand = tool->GetId();
493 if ( tool->IsEnabled() )
494 button.fsState |= TBSTATE_ENABLED;
495 if ( tool->IsToggled() )
496 button.fsState |= TBSTATE_CHECKED;
498 button.fsStyle = tool->CanBeToggled() ? TBSTYLE_CHECK
508 if ( !::SendMessage(GetHwnd(), TB_ADDBUTTONS,
509 (WPARAM)i, (LPARAM)buttons) )
511 wxLogLastError("TB_ADDBUTTONS");
516 // Deal with the controls finally
517 // ------------------------------
519 // adjust the controls size to fit nicely in the toolbar
521 for ( node = m_tools.GetFirst(); node; node = node->GetNext(), index++ )
523 wxToolBarToolBase *tool = node->GetData();
524 if ( !tool->IsControl() )
527 wxControl *control = tool->GetControl();
529 wxSize size = control->GetSize();
531 // the position of the leftmost controls corner
534 // note that we use TB_GETITEMRECT and not TB_GETRECT because the
535 // latter only appeared in v4.70 of comctl32.dll
537 if ( !SendMessage(GetHwnd(), TB_GETITEMRECT,
538 index, (LPARAM)(LPRECT)&r) )
540 wxLogLastError("TB_GETITEMRECT");
543 // TB_SETBUTTONINFO message is only supported by comctl32.dll 4.71+
544 #if defined(_WIN32_IE) && (_WIN32_IE >= 0x400 )
545 // available in headers, now check whether it is available now
547 if ( wxTheApp->GetComCtl32Version() >= 471 )
549 // set the (underlying) separators width to be that of the
552 tbbi.cbSize = sizeof(tbbi);
553 tbbi.dwMask = TBIF_SIZE;
555 if ( !SendMessage(GetHwnd(), TB_SETBUTTONINFO,
556 tool->GetId(), (LPARAM)&tbbi) )
558 // the id is probably invalid?
559 wxLogLastError("TB_SETBUTTONINFO");
564 #endif // comctl32.dll 4.71
565 // TB_SETBUTTONINFO unavailable
567 // try adding several separators to fit the controls width
568 int widthSep = r.right - r.left;
574 tbb.fsState = TBSTATE_ENABLED;
575 tbb.fsStyle = TBSTYLE_SEP;
577 size_t nSeparators = size.x / widthSep;
578 for ( size_t nSep = 0; nSep < nSeparators; nSep++ )
580 if ( !SendMessage(GetHwnd(), TB_INSERTBUTTON,
581 index, (LPARAM)&tbb) )
583 wxLogLastError("TB_INSERTBUTTON");
589 // remember the number of separators we used - we'd have to
590 // delete all of them later
591 ((wxToolBarTool *)tool)->SetSeparatorsCount(nSeparators);
593 // adjust the controls width to exactly cover the separators
594 control->SetSize((nSeparators + 1)*widthSep, -1);
597 // and position the control itself correctly vertically
598 int height = r.bottom - r.top;
599 int diff = height - size.y;
602 // the control is too high, resize to fit
603 control->SetSize(-1, height - 2);
608 control->Move(left == -1 ? r.left : left, r.top + (diff + 1) / 2);
611 // the max index is the "real" number of buttons - i.e. counting even the
612 // separators which we added just for aligning the controls
617 if ( m_maxRows == 0 )
619 // if not set yet, only one row
623 else if ( m_nButtons > 0 ) // vertical non empty toolbar
625 if ( m_maxRows == 0 )
627 // if not set yet, have one column
635 // ----------------------------------------------------------------------------
637 // ----------------------------------------------------------------------------
639 bool wxToolBar::OS2Command(
644 wxToolBarToolBase
* pTool
= FindById((int)nId
);
650 if (pTool->CanBeToggled())
652 LRESULT state = ::SendMessage(GetHwnd(), TB_GETSTATE, id, 0);
653 tool->SetToggle((state & TBSTATE_CHECKED) != 0);
656 bool toggled = tool->IsToggled();
658 // OnLeftClick() can veto the button state change - for buttons which may
659 // be toggled only, of couse
660 if ( !OnLeftClick((int)id, toggled) && tool->CanBeToggled() )
664 tool->SetToggle(toggled);
666 ::SendMessage(GetHwnd(), TB_CHECKBUTTON, id, MAKELONG(toggled, 0));
672 bool wxToolBar::OS2OnNotify(
680 // First check if this applies to us
681 NMHDR *hdr = (NMHDR *)lParam;
683 // the tooltips control created by the toolbar is sometimes Unicode, even
684 // in an ANSI application - this seems to be a bug in comctl32.dll v5
685 int code = (int)hdr->code;
686 if ( (code != TTN_NEEDTEXTA) && (code != TTN_NEEDTEXTW) )
689 HWND toolTipWnd = (HWND)::SendMessage((HWND)GetHWND(), TB_GETTOOLTIPS, 0, 0);
690 if ( toolTipWnd != hdr->hwndFrom )
693 LPTOOLTIPTEXT ttText = (LPTOOLTIPTEXT)lParam;
694 int id = (int)ttText->hdr.idFrom;
696 wxToolBarToolBase *tool = FindById(id);
700 const wxString& help = tool->GetShortHelp();
702 if ( !help.IsEmpty() )
704 if ( code == TTN_NEEDTEXTA )
706 ttText->lpszText = (wxChar *)help.c_str();
708 #if (_WIN32_IE >= 0x0300)
711 // FIXME this is a temp hack only until I understand better what
712 // must be done in both ANSI and Unicode builds
714 size_t lenAnsi = help.Len();
716 // MetroWerks doesn't like calling mbstowcs with NULL argument
717 size_t lenUnicode = 2*lenAnsi;
719 size_t lenUnicode = mbstowcs(NULL, help, lenAnsi);
722 // using the pointer of right type avoids us doing all sorts of
723 // pointer arithmetics ourselves
724 wchar_t *dst = (wchar_t *)ttText->szText,
725 *pwz = new wchar_t[lenUnicode + 1];
726 mbstowcs(pwz, help, lenAnsi + 1);
727 memcpy(dst, pwz, lenUnicode*sizeof(wchar_t));
729 // put the terminating _wide_ NUL
734 #endif // _WIN32_IE >= 0x0300
737 // For backward compatibility...
738 OnMouseEnter(tool->GetId());
743 // ----------------------------------------------------------------------------
745 // ----------------------------------------------------------------------------
747 void wxToolBar::SetToolBitmapSize(
751 wxToolBarBase::SetToolBitmapSize(rSize
);
753 // ::SendMessage(GetHwnd(), TB_SETBITMAPSIZE, 0, MAKELONG(size.x, size.y));
756 void wxToolBar::SetRows(
760 if (nRows
== m_maxRows
)
762 // avoid resizing the frame uselessly
767 // TRUE in wParam means to create at least as many rows, FALSE -
770 ::SendMessage(GetHwnd(), TB_SETROWS,
771 MAKEWPARAM(nRows, !(GetWindowStyle() & wxTB_VERTICAL)),
780 // The button size is bigger than the bitmap size
781 wxSize
wxToolBar::GetToolSize() const
785 // TB_GETBUTTONSIZE is supported from version 4.70
786 #if defined(_WIN32_IE) && (_WIN32_IE >= 0x300 )
787 if ( wxTheApp->GetComCtl32Version() >= 470 )
789 DWORD dw = ::SendMessage(GetHwnd(), TB_GETBUTTONSIZE, 0, 0);
791 return wxSize(LOWORD(dw), HIWORD(dw));
794 #endif // comctl32.dll 4.70+
797 return wxSize(m_defaultWidth + 8, m_defaultHeight + 7);
800 return wxSize(m_defaultWidth
+ 8, m_defaultHeight
+ 7);
803 wxToolBarToolBase
*wxToolBar::FindToolForPosition(
813 int nIndex
= 0; //(int)::SendMessage(GetHwnd(), TB_HITTEST, 0, (LPARAM)&pt);
816 // it's a separator or there is no tool at all there
817 return (wxToolBarToolBase
*)NULL
;
819 return(m_tools
.Item((size_t)nIndex
)->GetData());
822 void wxToolBar::UpdateSize()
824 // we must refresh the frame after the toolbar size (possibly) changed
825 wxFrame
* pFrame
= wxDynamicCast(GetParent(), wxFrame
);
829 // don't change the size, we just need to generate a WM_SIZE
833 if ( !GetWindowRect(GetHwndOf(frame), &r) )
835 wxLogLastError(_T("GetWindowRect"));
838 (void)::SendMessage(GetHwndOf(frame), WM_SIZE, SIZE_RESTORED,
839 MAKELPARAM(r.right - r.left, r.bottom - r.top));
844 // ----------------------------------------------------------------------------
846 // ----------------------------------------------------------------------------
848 void wxToolBar::DoEnableTool(
849 wxToolBarToolBase
* pTool
855 ::SendMessage(GetHwnd(), TB_ENABLEBUTTON,
856 (WPARAM)tool->GetId(), (LPARAM)MAKELONG(enable, 0));
860 void wxToolBar::DoToggleTool(
861 wxToolBarToolBase
* pTool
867 ::SendMessage(GetHwnd(), TB_CHECKBUTTON,
868 (WPARAM)tool->GetId(), (LPARAM)MAKELONG(toggle, 0));
872 void wxToolBar::DoSetToggle(
873 wxToolBarToolBase
* pTool
877 // VZ: AFAIK, the button has to be created either with TBSTYLE_CHECK or
878 // without, so we really need to delete the button and recreate it here
879 wxFAIL_MSG( _T("not implemented") );
882 // ----------------------------------------------------------------------------
884 // ----------------------------------------------------------------------------
886 // Responds to colour changes, and passes event on to children.
887 void wxToolBar::OnSysColourChanged(
888 wxSysColourChangedEvent
& rEvent
893 m_backgroundColour = wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)),
894 GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE)));
902 // Propagate the event to the non-top-level children
903 wxWindow::OnSysColourChanged(rEvent
);
906 void wxToolBar::OnMouseEvent(
910 if (rEvent
.RightDown())
912 // For now, we don't have an id. Later we could
913 // try finding the tool.
914 OnRightClick( (int)-1
925 MRESULT
wxToolBar::OS2WindowProc(
935 // calculate our minor dimenstion ourselves - we're confusing the
936 // standard logic (TB_AUTOSIZE) with our horizontal toolbars and other
939 if ( ::SendMessage(GetHwnd(), TB_GETITEMRECT, 0, (LPARAM)&r) )
943 if ( GetWindowStyle() & wxTB_VERTICAL )
945 w = r.right - r.left;
948 w *= (m_nButtons + m_maxRows - 1)/m_maxRows;
955 h = r.bottom - r.top;
958 h += 6; // FIXME: this is the separator line height...
963 if ( MAKELPARAM(w, h) != lParam )
965 // size really changed
974 return wxControl::MSWWindowProc(nMsg, wParam, lParam);
979 // ----------------------------------------------------------------------------
981 // ----------------------------------------------------------------------------
983 // These are the default colors used to map the bitmap colors to the current
984 // system colors. Note that they are in BGR format because this is what Windows
985 // wants (and not RGB)
987 #define BGR_BUTTONTEXT (RGB(000,000,000)) // black
988 #define BGR_BUTTONSHADOW (RGB(128,128,128)) // dark grey
989 #define BGR_BUTTONFACE (RGB(192,192,192)) // bright grey
990 #define BGR_BUTTONHILIGHT (RGB(255,255,255)) // white
991 #define BGR_BACKGROUNDSEL (RGB(255,000,000)) // blue
992 #define BGR_BACKGROUND (RGB(255,000,255)) // magenta
1002 COLORMAP ColorMap[] =
1004 {BGR_BUTTONTEXT, COLOR_BTNTEXT}, // black
1005 {BGR_BUTTONSHADOW, COLOR_BTNSHADOW}, // dark grey
1006 {BGR_BUTTONFACE, COLOR_BTNFACE}, // bright grey
1007 {BGR_BUTTONHILIGHT, COLOR_BTNHIGHLIGHT},// white
1008 {BGR_BACKGROUNDSEL, COLOR_HIGHLIGHT}, // blue
1009 {BGR_BACKGROUND, COLOR_WINDOW} // magenta
1012 int NUM_MAPS = (sizeof(ColorMap)/sizeof(COLORMAP));
1014 for ( n = 0; n < NUM_MAPS; n++)
1016 ColorMap[n].to = ::GetSysColor(ColorMap[n].to);
1020 HDC hdcMem = CreateCompatibleDC(NULL);
1024 hbmOld = (HBITMAP) SelectObject(hdcMem, hBitmap);
1027 for ( i = 0; i < width; i++)
1029 for ( j = 0; j < height; j++)
1031 COLORREF pixel = ::GetPixel(hdcMem, i, j);
1033 // BYTE red = GetRValue(pixel);
1034 // BYTE green = GetGValue(pixel);
1035 // BYTE blue = GetBValue(pixel);
1038 for ( k = 0; k < NUM_MAPS; k ++)
1040 if ( ColorMap[k].from == pixel )
1042 // COLORREF actualPixel = ::SetPixel(hdcMem, i, j, ColorMap[k].to);
1050 SelectObject(hdcMem, hbmOld);
1051 DeleteObject(hdcMem);
1056 // Some experiments...
1058 // What we want to do is create another bitmap which has a depth of 4,
1059 // and set the bits. So probably we want to convert this HBITMAP into a
1060 // DIB, then call SetDIBits.
1061 // AAAGH. The stupid thing is that if newBitmap has a depth of 4 (less than that of
1062 // the screen), then SetDIBits fails.
1063 HBITMAP newBitmap
= ::CreateBitmap(totalBitmapWidth
, totalBitmapHeight
, 1, 4, NULL
);
1064 HANDLE newDIB
= ::BitmapToDIB((HBITMAP
) m_hBitmap
, NULL
);
1065 LPBITMAPINFOHEADER lpbmi
= (LPBITMAPINFOHEADER
) GlobalLock(newDIB
);
1068 // LPBITMAPINFOHEADER lpbmi = (LPBITMAPINFOHEADER) newDIB;
1070 int result
= ::SetDIBits(dc
, newBitmap
, 0, lpbmi
->biHeight
, FindDIBBits((LPSTR
)lpbmi
), (LPBITMAPINFO
)lpbmi
,
1072 DWORD err
= GetLastError();
1074 ::ReleaseDC(NULL
, dc
);
1077 GlobalUnlock (newDIB
);
1078 GlobalFree (newDIB
);
1080 // WXHBITMAP hBitmap2 = wxCreateMappedBitmap((WXHINSTANCE) wxGetInstance(), (WXHBITMAP) m_hBitmap);
1081 // Substitute our new bitmap for the old one
1082 ::DeleteObject((HBITMAP
) m_hBitmap
);
1083 m_hBitmap
= (WXHBITMAP
) newBitmap
;