]>
git.saurik.com Git - wxWidgets.git/blob - src/os2/toolbar.cpp
24a0aa8aff484df33a5195cfdaf1278685a5b2e3
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 wxBitmap
& rBitmap1
88 ,const wxBitmap
& rBitmap2
90 ,wxObject
* pClientData
91 ,const wxString
& rShortHelpString
92 ,const wxString
& rLongHelpString
93 ) : wxToolBarToolBase( pTbar
106 inline wxToolBarTool( wxToolBar
* pTbar
108 ) : wxToolBarToolBase( pTbar
115 // set/get the number of separators which we use to cover the space used by
116 // a control in the toolbar
117 inline void SetSeparatorsCount(size_t nCount
) { m_nSepCount
= nCount
; }
118 inline size_t GetSeparatorsCount(void) const { return m_nSepCount
; }
125 // ============================================================================
127 // ============================================================================
129 // ----------------------------------------------------------------------------
131 // ----------------------------------------------------------------------------
133 wxToolBarToolBase
* wxToolBar::CreateTool(
135 , const wxBitmap
& rBitmap1
136 , const wxBitmap
& rBitmap2
138 , wxObject
* pClientData
139 , const wxString
& rShortHelpString
140 , const wxString
& rLongHelpString
143 return(new wxToolBarTool( this
154 wxToolBarToolBase
* wxToolBar::CreateTool(
158 return(new wxToolBarTool( this
163 // ----------------------------------------------------------------------------
164 // wxToolBar construction
165 // ----------------------------------------------------------------------------
167 void wxToolBar::Init()
171 m_defaultWidth
= DEFAULTBITMAPX
;
172 m_defaultHeight
= DEFAULTBITMAPY
;
175 bool wxToolBar::Create(
178 , const wxPoint
& rPos
179 , const wxSize
& rSize
181 , const wxString
& rName
184 // common initialisation
185 if (!CreateControl( pParent
196 DWORD msflags
= 0; // WS_VISIBLE | WS_CHILD always included
200 if (lStyle & wxBORDER)
201 msflags |= WS_BORDER;
202 msflags |= TBSTYLE_TOOLTIPS;
204 if (style & wxTB_FLAT)
206 if (wxTheApp->GetComCtl32Version() > 400)
207 msflags |= TBSTYLE_FLAT;
210 // MSW-specific initialisation
211 if ( !wxControl::MSWCreateControl(TOOLBARCLASSNAME, msflags) )
214 // toolbar-specific post initialisation
215 ::SendMessage(GetHwnd(), TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
217 // set up the colors and fonts
218 wxRGBToColour(m_backgroundColour, GetSysColor(COLOR_BTNFACE));
219 m_foregroundColour = *wxBLACK;
221 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
232 height = m_defaultHeight;
238 SetSize(x, y, width, height);
243 wxToolBar::~wxToolBar()
247 ::GpiDeleteBitmap((HBITMAP
) m_hBitmap
);
251 // ----------------------------------------------------------------------------
252 // adding/removing tools
253 // ----------------------------------------------------------------------------
255 bool wxToolBar::DoInsertTool(
256 size_t WXUNUSED(nPos
)
257 , wxToolBarToolBase
* pTool
260 // nothing special to do here - we really create the toolbar buttons in
266 bool wxToolBar::DoDeleteTool(
268 , wxToolBarToolBase
* pTool
271 // normally, we only delete one button, but we use several separators to
272 // cover the space used by one control sometimes (with old comctl32.dll)
273 size_t nButtonsToDelete
= 1;
275 // get the size of the button we're going to delete
280 if ( !::SendMessage(GetHwnd(), TB_GETITEMRECT, pos, (LPARAM)&r) )
282 wxLogLastError(_T("TB_GETITEMRECT"));
285 int width = r.right - r.left;
287 if ( tool->IsControl() )
289 nButtonsToDelete = ((wxToolBarTool *)tool)->GetSeparatorsCount();
291 width *= nButtonsToDelete;
294 while ( nButtonsToDelete-- > 0 )
296 if ( !::SendMessage(GetHwnd(), TB_DELETEBUTTON, pos, 0) )
298 wxLogLastError("TB_DELETEBUTTON");
306 m_nButtons -= nButtonsToDelete;
308 // reposition all the controls after this button
309 wxToolBarToolsList::Node *node = m_tools.Item(pos);
310 for ( node = node->GetNext(); node; node = node->GetNext() )
312 wxToolBarToolBase *tool2 = node->GetData();
313 if ( tool2->IsControl() )
316 wxControl *control = tool2->GetControl();
317 control->GetPosition(&x, NULL);
318 control->Move(x - width, -1);
325 bool wxToolBar::Realize()
327 size_t nTools
= GetToolsCount();
335 bool bIsVertical
= (GetWindowStyle() & wxTB_VERTICAL
) != 0;
339 // First, add the bitmap: we use one bitmap for all toolbar buttons
340 // ----------------------------------------------------------------
342 // if we already have a bitmap, we'll replace the existing one - otherwise
343 // we'll install a new one
344 HBITMAP oldToolBarBitmap = (HBITMAP)m_hBitmap;
346 int totalBitmapWidth = (int)(m_defaultWidth * nTools);
347 int totalBitmapHeight = (int)m_defaultHeight;
349 // Create a bitmap for all the tool bitmaps
350 HBITMAP hBitmap = ::CreateCompatibleBitmap(ScreenHDC(),
355 wxLogLastError(_T("CreateCompatibleBitmap"));
360 m_hBitmap = (WXHBITMAP)hBitmap;
362 // Now blit all the tools onto this bitmap
363 HDC memoryDC = ::CreateCompatibleDC(NULL);
364 HBITMAP oldBitmap = (HBITMAP) ::SelectObject(memoryDC, hBitmap);
366 HDC memoryDC2 = ::CreateCompatibleDC(NULL);
368 // the button position
371 // the number of buttons (not separators)
374 wxToolBarToolsList::Node *node = m_tools.GetFirst();
377 wxToolBarToolBase *tool = node->GetData();
378 if ( tool->IsButton() )
380 HBITMAP hbmp = GetHbitmapOf(tool->GetBitmap1());
383 HBITMAP oldBitmap2 = (HBITMAP)::SelectObject(memoryDC2, hbmp);
384 if ( !BitBlt(memoryDC, x, 0, m_defaultWidth, m_defaultHeight,
385 memoryDC2, 0, 0, SRCCOPY) )
387 wxLogLastError("BitBlt");
390 ::SelectObject(memoryDC2, oldBitmap2);
394 wxFAIL_MSG( _T("invalid tool button bitmap") );
397 // still inc width and number of buttons because otherwise the
398 // subsequent buttons will all be shifted which is rather confusing
399 // (and like this you'd see immediately which bitmap was bad)
404 node = node->GetNext();
407 ::SelectObject(memoryDC, oldBitmap);
408 ::DeleteDC(memoryDC);
409 ::DeleteDC(memoryDC2);
411 // Map to system colours
412 wxMapBitmap(hBitmap, totalBitmapWidth, totalBitmapHeight);
414 if ( oldToolBarBitmap )
416 TBREPLACEBITMAP replaceBitmap;
417 replaceBitmap.hInstOld = NULL;
418 replaceBitmap.hInstNew = NULL;
419 replaceBitmap.nIDOld = (UINT) oldToolBarBitmap;
420 replaceBitmap.nIDNew = (UINT) hBitmap;
421 replaceBitmap.nButtons = nButtons;
422 if ( !::SendMessage(GetHwnd(), TB_REPLACEBITMAP,
423 0, (LPARAM) &replaceBitmap) )
425 wxFAIL_MSG(wxT("Could not add bitmap to toolbar"));
428 ::DeleteObject(oldToolBarBitmap);
430 // Now delete all the buttons
431 for ( size_t pos = 0; pos < m_nButtons; pos++ )
433 if ( !::SendMessage(GetHwnd(), TB_DELETEBUTTON, 0, 0) )
435 wxLogLastError("TB_DELETEBUTTON");
439 else // no old bitmap
441 TBADDBITMAP addBitmap;
443 addBitmap.nID = (UINT) hBitmap;
444 if ( ::SendMessage(GetHwnd(), TB_ADDBITMAP,
445 (WPARAM) nButtons, (LPARAM)&addBitmap) == -1 )
447 wxFAIL_MSG(wxT("Could not add bitmap to toolbar"));
451 // Next add the buttons and separators
452 // -----------------------------------
454 TBBUTTON *buttons = new TBBUTTON[nTools];
456 // this array will hold the indices of all controls in the toolbar
457 wxArrayInt controlIds;
462 for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
464 wxToolBarToolBase *tool = node->GetData();
466 // don't add separators to the vertical toolbar - looks ugly
467 if ( isVertical && tool->IsSeparator() )
470 TBBUTTON& button = buttons[i];
472 wxZeroMemory(button);
474 switch ( tool->GetStyle() )
476 case wxTOOL_STYLE_CONTROL:
477 button.idCommand = tool->GetId();
478 // fall through: create just a separator too
480 case wxTOOL_STYLE_SEPARATOR:
481 button.fsState = TBSTATE_ENABLED;
482 button.fsStyle = TBSTYLE_SEP;
485 case wxTOOL_STYLE_BUTTON:
486 button.iBitmap = bitmapId;
487 button.idCommand = tool->GetId();
489 if ( tool->IsEnabled() )
490 button.fsState |= TBSTATE_ENABLED;
491 if ( tool->IsToggled() )
492 button.fsState |= TBSTATE_CHECKED;
494 button.fsStyle = tool->CanBeToggled() ? TBSTYLE_CHECK
504 if ( !::SendMessage(GetHwnd(), TB_ADDBUTTONS,
505 (WPARAM)i, (LPARAM)buttons) )
507 wxLogLastError("TB_ADDBUTTONS");
512 // Deal with the controls finally
513 // ------------------------------
515 // adjust the controls size to fit nicely in the toolbar
517 for ( node = m_tools.GetFirst(); node; node = node->GetNext(), index++ )
519 wxToolBarToolBase *tool = node->GetData();
520 if ( !tool->IsControl() )
523 wxControl *control = tool->GetControl();
525 wxSize size = control->GetSize();
527 // the position of the leftmost controls corner
530 // note that we use TB_GETITEMRECT and not TB_GETRECT because the
531 // latter only appeared in v4.70 of comctl32.dll
533 if ( !SendMessage(GetHwnd(), TB_GETITEMRECT,
534 index, (LPARAM)(LPRECT)&r) )
536 wxLogLastError("TB_GETITEMRECT");
539 // TB_SETBUTTONINFO message is only supported by comctl32.dll 4.71+
540 #if defined(_WIN32_IE) && (_WIN32_IE >= 0x400 )
541 // available in headers, now check whether it is available now
543 if ( wxTheApp->GetComCtl32Version() >= 471 )
545 // set the (underlying) separators width to be that of the
548 tbbi.cbSize = sizeof(tbbi);
549 tbbi.dwMask = TBIF_SIZE;
551 if ( !SendMessage(GetHwnd(), TB_SETBUTTONINFO,
552 tool->GetId(), (LPARAM)&tbbi) )
554 // the id is probably invalid?
555 wxLogLastError("TB_SETBUTTONINFO");
560 #endif // comctl32.dll 4.71
561 // TB_SETBUTTONINFO unavailable
563 // try adding several separators to fit the controls width
564 int widthSep = r.right - r.left;
570 tbb.fsState = TBSTATE_ENABLED;
571 tbb.fsStyle = TBSTYLE_SEP;
573 size_t nSeparators = size.x / widthSep;
574 for ( size_t nSep = 0; nSep < nSeparators; nSep++ )
576 if ( !SendMessage(GetHwnd(), TB_INSERTBUTTON,
577 index, (LPARAM)&tbb) )
579 wxLogLastError("TB_INSERTBUTTON");
585 // remember the number of separators we used - we'd have to
586 // delete all of them later
587 ((wxToolBarTool *)tool)->SetSeparatorsCount(nSeparators);
589 // adjust the controls width to exactly cover the separators
590 control->SetSize((nSeparators + 1)*widthSep, -1);
593 // and position the control itself correctly vertically
594 int height = r.bottom - r.top;
595 int diff = height - size.y;
598 // the control is too high, resize to fit
599 control->SetSize(-1, height - 2);
604 control->Move(left == -1 ? r.left : left, r.top + (diff + 1) / 2);
607 // the max index is the "real" number of buttons - i.e. counting even the
608 // separators which we added just for aligning the controls
613 if ( m_maxRows == 0 )
615 // if not set yet, only one row
619 else if ( m_nButtons > 0 ) // vertical non empty toolbar
621 if ( m_maxRows == 0 )
623 // if not set yet, have one column
631 // ----------------------------------------------------------------------------
633 // ----------------------------------------------------------------------------
635 bool wxToolBar::OS2Command(
640 wxToolBarToolBase
* pTool
= FindById((int)nId
);
646 if (pTool->CanBeToggled())
648 LRESULT state = ::SendMessage(GetHwnd(), TB_GETSTATE, id, 0);
649 tool->SetToggle((state & TBSTATE_CHECKED) != 0);
652 bool toggled = tool->IsToggled();
654 // OnLeftClick() can veto the button state change - for buttons which may
655 // be toggled only, of couse
656 if ( !OnLeftClick((int)id, toggled) && tool->CanBeToggled() )
660 tool->SetToggle(toggled);
662 ::SendMessage(GetHwnd(), TB_CHECKBUTTON, id, MAKELONG(toggled, 0));
668 bool wxToolBar::OS2OnNotify(
676 // First check if this applies to us
677 NMHDR *hdr = (NMHDR *)lParam;
679 // the tooltips control created by the toolbar is sometimes Unicode, even
680 // in an ANSI application - this seems to be a bug in comctl32.dll v5
681 int code = (int)hdr->code;
682 if ( (code != TTN_NEEDTEXTA) && (code != TTN_NEEDTEXTW) )
685 HWND toolTipWnd = (HWND)::SendMessage((HWND)GetHWND(), TB_GETTOOLTIPS, 0, 0);
686 if ( toolTipWnd != hdr->hwndFrom )
689 LPTOOLTIPTEXT ttText = (LPTOOLTIPTEXT)lParam;
690 int id = (int)ttText->hdr.idFrom;
692 wxToolBarToolBase *tool = FindById(id);
696 const wxString& help = tool->GetShortHelp();
698 if ( !help.IsEmpty() )
700 if ( code == TTN_NEEDTEXTA )
702 ttText->lpszText = (wxChar *)help.c_str();
704 #if (_WIN32_IE >= 0x0300)
707 // FIXME this is a temp hack only until I understand better what
708 // must be done in both ANSI and Unicode builds
710 size_t lenAnsi = help.Len();
712 // MetroWerks doesn't like calling mbstowcs with NULL argument
713 size_t lenUnicode = 2*lenAnsi;
715 size_t lenUnicode = mbstowcs(NULL, help, lenAnsi);
718 // using the pointer of right type avoids us doing all sorts of
719 // pointer arithmetics ourselves
720 wchar_t *dst = (wchar_t *)ttText->szText,
721 *pwz = new wchar_t[lenUnicode + 1];
722 mbstowcs(pwz, help, lenAnsi + 1);
723 memcpy(dst, pwz, lenUnicode*sizeof(wchar_t));
725 // put the terminating _wide_ NUL
730 #endif // _WIN32_IE >= 0x0300
733 // For backward compatibility...
734 OnMouseEnter(tool->GetId());
739 // ----------------------------------------------------------------------------
741 // ----------------------------------------------------------------------------
743 void wxToolBar::SetToolBitmapSize(
747 wxToolBarBase::SetToolBitmapSize(rSize
);
749 // ::SendMessage(GetHwnd(), TB_SETBITMAPSIZE, 0, MAKELONG(size.x, size.y));
752 void wxToolBar::SetRows(
756 if (nRows
== m_maxRows
)
758 // avoid resizing the frame uselessly
763 // TRUE in wParam means to create at least as many rows, FALSE -
766 ::SendMessage(GetHwnd(), TB_SETROWS,
767 MAKEWPARAM(nRows, !(GetWindowStyle() & wxTB_VERTICAL)),
776 // The button size is bigger than the bitmap size
777 wxSize
wxToolBar::GetToolSize() const
781 // TB_GETBUTTONSIZE is supported from version 4.70
782 #if defined(_WIN32_IE) && (_WIN32_IE >= 0x300 )
783 if ( wxTheApp->GetComCtl32Version() >= 470 )
785 DWORD dw = ::SendMessage(GetHwnd(), TB_GETBUTTONSIZE, 0, 0);
787 return wxSize(LOWORD(dw), HIWORD(dw));
790 #endif // comctl32.dll 4.70+
793 return wxSize(m_defaultWidth + 8, m_defaultHeight + 7);
796 return wxSize(m_defaultWidth
+ 8, m_defaultHeight
+ 7);
799 wxToolBarToolBase
*wxToolBar::FindToolForPosition(
809 int nIndex
= 0; //(int)::SendMessage(GetHwnd(), TB_HITTEST, 0, (LPARAM)&pt);
812 // it's a separator or there is no tool at all there
813 return (wxToolBarToolBase
*)NULL
;
815 return(m_tools
.Item((size_t)nIndex
)->GetData());
818 void wxToolBar::UpdateSize()
820 // we must refresh the frame after the toolbar size (possibly) changed
821 wxFrame
* pFrame
= wxDynamicCast(GetParent(), wxFrame
);
825 // don't change the size, we just need to generate a WM_SIZE
829 if ( !GetWindowRect(GetHwndOf(frame), &r) )
831 wxLogLastError(_T("GetWindowRect"));
834 (void)::SendMessage(GetHwndOf(frame), WM_SIZE, SIZE_RESTORED,
835 MAKELPARAM(r.right - r.left, r.bottom - r.top));
840 // ----------------------------------------------------------------------------
842 // ----------------------------------------------------------------------------
844 void wxToolBar::DoEnableTool(
845 wxToolBarToolBase
* pTool
851 ::SendMessage(GetHwnd(), TB_ENABLEBUTTON,
852 (WPARAM)tool->GetId(), (LPARAM)MAKELONG(enable, 0));
856 void wxToolBar::DoToggleTool(
857 wxToolBarToolBase
* pTool
863 ::SendMessage(GetHwnd(), TB_CHECKBUTTON,
864 (WPARAM)tool->GetId(), (LPARAM)MAKELONG(toggle, 0));
868 void wxToolBar::DoSetToggle(
869 wxToolBarToolBase
* pTool
873 // VZ: AFAIK, the button has to be created either with TBSTYLE_CHECK or
874 // without, so we really need to delete the button and recreate it here
875 wxFAIL_MSG( _T("not implemented") );
878 // ----------------------------------------------------------------------------
880 // ----------------------------------------------------------------------------
882 // Responds to colour changes, and passes event on to children.
883 void wxToolBar::OnSysColourChanged(
884 wxSysColourChangedEvent
& rEvent
889 m_backgroundColour = wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)),
890 GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE)));
898 // Propagate the event to the non-top-level children
899 wxWindow::OnSysColourChanged(rEvent
);
902 void wxToolBar::OnMouseEvent(
906 if (rEvent
.RightDown())
908 // For now, we don't have an id. Later we could
909 // try finding the tool.
910 OnRightClick( (int)-1
921 MRESULT
wxToolBar::OS2WindowProc(
931 // calculate our minor dimenstion ourselves - we're confusing the
932 // standard logic (TB_AUTOSIZE) with our horizontal toolbars and other
935 if ( ::SendMessage(GetHwnd(), TB_GETITEMRECT, 0, (LPARAM)&r) )
939 if ( GetWindowStyle() & wxTB_VERTICAL )
941 w = r.right - r.left;
944 w *= (m_nButtons + m_maxRows - 1)/m_maxRows;
951 h = r.bottom - r.top;
954 h += 6; // FIXME: this is the separator line height...
959 if ( MAKELPARAM(w, h) != lParam )
961 // size really changed
970 return wxControl::MSWWindowProc(nMsg, wParam, lParam);
975 // ----------------------------------------------------------------------------
977 // ----------------------------------------------------------------------------
979 // These are the default colors used to map the bitmap colors to the current
980 // system colors. Note that they are in BGR format because this is what Windows
981 // wants (and not RGB)
983 #define BGR_BUTTONTEXT (RGB(000,000,000)) // black
984 #define BGR_BUTTONSHADOW (RGB(128,128,128)) // dark grey
985 #define BGR_BUTTONFACE (RGB(192,192,192)) // bright grey
986 #define BGR_BUTTONHILIGHT (RGB(255,255,255)) // white
987 #define BGR_BACKGROUNDSEL (RGB(255,000,000)) // blue
988 #define BGR_BACKGROUND (RGB(255,000,255)) // magenta
998 COLORMAP ColorMap[] =
1000 {BGR_BUTTONTEXT, COLOR_BTNTEXT}, // black
1001 {BGR_BUTTONSHADOW, COLOR_BTNSHADOW}, // dark grey
1002 {BGR_BUTTONFACE, COLOR_BTNFACE}, // bright grey
1003 {BGR_BUTTONHILIGHT, COLOR_BTNHIGHLIGHT},// white
1004 {BGR_BACKGROUNDSEL, COLOR_HIGHLIGHT}, // blue
1005 {BGR_BACKGROUND, COLOR_WINDOW} // magenta
1008 int NUM_MAPS = (sizeof(ColorMap)/sizeof(COLORMAP));
1010 for ( n = 0; n < NUM_MAPS; n++)
1012 ColorMap[n].to = ::GetSysColor(ColorMap[n].to);
1016 HDC hdcMem = CreateCompatibleDC(NULL);
1020 hbmOld = (HBITMAP) SelectObject(hdcMem, hBitmap);
1023 for ( i = 0; i < width; i++)
1025 for ( j = 0; j < height; j++)
1027 COLORREF pixel = ::GetPixel(hdcMem, i, j);
1029 // BYTE red = GetRValue(pixel);
1030 // BYTE green = GetGValue(pixel);
1031 // BYTE blue = GetBValue(pixel);
1034 for ( k = 0; k < NUM_MAPS; k ++)
1036 if ( ColorMap[k].from == pixel )
1038 // COLORREF actualPixel = ::SetPixel(hdcMem, i, j, ColorMap[k].to);
1046 SelectObject(hdcMem, hbmOld);
1047 DeleteObject(hdcMem);
1052 // Some experiments...
1054 // What we want to do is create another bitmap which has a depth of 4,
1055 // and set the bits. So probably we want to convert this HBITMAP into a
1056 // DIB, then call SetDIBits.
1057 // AAAGH. The stupid thing is that if newBitmap has a depth of 4 (less than that of
1058 // the screen), then SetDIBits fails.
1059 HBITMAP newBitmap
= ::CreateBitmap(totalBitmapWidth
, totalBitmapHeight
, 1, 4, NULL
);
1060 HANDLE newDIB
= ::BitmapToDIB((HBITMAP
) m_hBitmap
, NULL
);
1061 LPBITMAPINFOHEADER lpbmi
= (LPBITMAPINFOHEADER
) GlobalLock(newDIB
);
1064 // LPBITMAPINFOHEADER lpbmi = (LPBITMAPINFOHEADER) newDIB;
1066 int result
= ::SetDIBits(dc
, newBitmap
, 0, lpbmi
->biHeight
, FindDIBBits((LPSTR
)lpbmi
), (LPBITMAPINFO
)lpbmi
,
1068 DWORD err
= GetLastError();
1070 ::ReleaseDC(NULL
, dc
);
1073 GlobalUnlock (newDIB
);
1074 GlobalFree (newDIB
);
1076 // WXHBITMAP hBitmap2 = wxCreateMappedBitmap((WXHINSTANCE) wxGetInstance(), (WXHBITMAP) m_hBitmap);
1077 // Substitute our new bitmap for the old one
1078 ::DeleteObject((HBITMAP
) m_hBitmap
);
1079 m_hBitmap
= (WXHBITMAP
) newBitmap
;