]>
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 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
195 DWORD msflags
= 0; // WS_VISIBLE | WS_CHILD always included
199 if (lStyle & wxBORDER)
200 msflags |= WS_BORDER;
201 msflags |= TBSTYLE_TOOLTIPS;
203 if (style & wxTB_FLAT)
205 if (wxTheApp->GetComCtl32Version() > 400)
206 msflags |= TBSTYLE_FLAT;
209 // MSW-specific initialisation
210 if ( !wxControl::MSWCreateControl(TOOLBARCLASSNAME, msflags) )
213 // toolbar-specific post initialisation
214 ::SendMessage(GetHwnd(), TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
216 // set up the colors and fonts
217 wxRGBToColour(m_backgroundColour, GetSysColor(COLOR_BTNFACE));
218 m_foregroundColour = *wxBLACK;
220 SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT));
231 height = m_defaultHeight;
237 SetSize(x, y, width, height);
242 wxToolBar::~wxToolBar()
246 ::GpiDeleteBitmap((HBITMAP
) m_hBitmap
);
250 // ----------------------------------------------------------------------------
251 // adding/removing tools
252 // ----------------------------------------------------------------------------
254 bool wxToolBar::DoInsertTool(
255 size_t WXUNUSED(nPos
)
256 , wxToolBarToolBase
* pTool
259 // nothing special to do here - we really create the toolbar buttons in
265 bool wxToolBar::DoDeleteTool(
267 , wxToolBarToolBase
* pTool
270 // normally, we only delete one button, but we use several separators to
271 // cover the space used by one control sometimes (with old comctl32.dll)
272 size_t nButtonsToDelete
= 1;
274 // get the size of the button we're going to delete
279 if ( !::SendMessage(GetHwnd(), TB_GETITEMRECT, pos, (LPARAM)&r) )
281 wxLogLastError(_T("TB_GETITEMRECT"));
284 int width = r.right - r.left;
286 if ( tool->IsControl() )
288 nButtonsToDelete = ((wxToolBarTool *)tool)->GetSeparatorsCount();
290 width *= nButtonsToDelete;
293 while ( nButtonsToDelete-- > 0 )
295 if ( !::SendMessage(GetHwnd(), TB_DELETEBUTTON, pos, 0) )
297 wxLogLastError("TB_DELETEBUTTON");
305 m_nButtons -= nButtonsToDelete;
307 // reposition all the controls after this button
308 wxToolBarToolsList::Node *node = m_tools.Item(pos);
309 for ( node = node->GetNext(); node; node = node->GetNext() )
311 wxToolBarToolBase *tool2 = node->GetData();
312 if ( tool2->IsControl() )
315 wxControl *control = tool2->GetControl();
316 control->GetPosition(&x, NULL);
317 control->Move(x - width, -1);
324 bool wxToolBar::Realize()
326 size_t nTools
= GetToolsCount();
334 bool bIsVertical
= (GetWindowStyle() & wxTB_VERTICAL
) != 0;
338 // First, add the bitmap: we use one bitmap for all toolbar buttons
339 // ----------------------------------------------------------------
341 // if we already have a bitmap, we'll replace the existing one - otherwise
342 // we'll install a new one
343 HBITMAP oldToolBarBitmap = (HBITMAP)m_hBitmap;
345 int totalBitmapWidth = (int)(m_defaultWidth * nTools);
346 int totalBitmapHeight = (int)m_defaultHeight;
348 // Create a bitmap for all the tool bitmaps
349 HBITMAP hBitmap = ::CreateCompatibleBitmap(ScreenHDC(),
354 wxLogLastError(_T("CreateCompatibleBitmap"));
359 m_hBitmap = (WXHBITMAP)hBitmap;
361 // Now blit all the tools onto this bitmap
362 HDC memoryDC = ::CreateCompatibleDC(NULL);
363 HBITMAP oldBitmap = (HBITMAP) ::SelectObject(memoryDC, hBitmap);
365 HDC memoryDC2 = ::CreateCompatibleDC(NULL);
367 // the button position
370 // the number of buttons (not separators)
373 wxToolBarToolsList::Node *node = m_tools.GetFirst();
376 wxToolBarToolBase *tool = node->GetData();
377 if ( tool->IsButton() )
379 HBITMAP hbmp = GetHbitmapOf(tool->GetBitmap1());
382 HBITMAP oldBitmap2 = (HBITMAP)::SelectObject(memoryDC2, hbmp);
383 if ( !BitBlt(memoryDC, x, 0, m_defaultWidth, m_defaultHeight,
384 memoryDC2, 0, 0, SRCCOPY) )
386 wxLogLastError("BitBlt");
389 ::SelectObject(memoryDC2, oldBitmap2);
393 wxFAIL_MSG( _T("invalid tool button bitmap") );
396 // still inc width and number of buttons because otherwise the
397 // subsequent buttons will all be shifted which is rather confusing
398 // (and like this you'd see immediately which bitmap was bad)
403 node = node->GetNext();
406 ::SelectObject(memoryDC, oldBitmap);
407 ::DeleteDC(memoryDC);
408 ::DeleteDC(memoryDC2);
410 // Map to system colours
411 wxMapBitmap(hBitmap, totalBitmapWidth, totalBitmapHeight);
413 if ( oldToolBarBitmap )
415 TBREPLACEBITMAP replaceBitmap;
416 replaceBitmap.hInstOld = NULL;
417 replaceBitmap.hInstNew = NULL;
418 replaceBitmap.nIDOld = (UINT) oldToolBarBitmap;
419 replaceBitmap.nIDNew = (UINT) hBitmap;
420 replaceBitmap.nButtons = nButtons;
421 if ( !::SendMessage(GetHwnd(), TB_REPLACEBITMAP,
422 0, (LPARAM) &replaceBitmap) )
424 wxFAIL_MSG(wxT("Could not add bitmap to toolbar"));
427 ::DeleteObject(oldToolBarBitmap);
429 // Now delete all the buttons
430 for ( size_t pos = 0; pos < m_nButtons; pos++ )
432 if ( !::SendMessage(GetHwnd(), TB_DELETEBUTTON, 0, 0) )
434 wxLogLastError("TB_DELETEBUTTON");
438 else // no old bitmap
440 TBADDBITMAP addBitmap;
442 addBitmap.nID = (UINT) hBitmap;
443 if ( ::SendMessage(GetHwnd(), TB_ADDBITMAP,
444 (WPARAM) nButtons, (LPARAM)&addBitmap) == -1 )
446 wxFAIL_MSG(wxT("Could not add bitmap to toolbar"));
450 // Next add the buttons and separators
451 // -----------------------------------
453 TBBUTTON *buttons = new TBBUTTON[nTools];
455 // this array will hold the indices of all controls in the toolbar
456 wxArrayInt controlIds;
461 for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
463 wxToolBarToolBase *tool = node->GetData();
465 // don't add separators to the vertical toolbar - looks ugly
466 if ( isVertical && tool->IsSeparator() )
469 TBBUTTON& button = buttons[i];
471 wxZeroMemory(button);
473 switch ( tool->GetStyle() )
475 case wxTOOL_STYLE_CONTROL:
476 button.idCommand = tool->GetId();
477 // fall through: create just a separator too
479 case wxTOOL_STYLE_SEPARATOR:
480 button.fsState = TBSTATE_ENABLED;
481 button.fsStyle = TBSTYLE_SEP;
484 case wxTOOL_STYLE_BUTTON:
485 button.iBitmap = bitmapId;
486 button.idCommand = tool->GetId();
488 if ( tool->IsEnabled() )
489 button.fsState |= TBSTATE_ENABLED;
490 if ( tool->IsToggled() )
491 button.fsState |= TBSTATE_CHECKED;
493 button.fsStyle = tool->CanBeToggled() ? TBSTYLE_CHECK
503 if ( !::SendMessage(GetHwnd(), TB_ADDBUTTONS,
504 (WPARAM)i, (LPARAM)buttons) )
506 wxLogLastError("TB_ADDBUTTONS");
511 // Deal with the controls finally
512 // ------------------------------
514 // adjust the controls size to fit nicely in the toolbar
516 for ( node = m_tools.GetFirst(); node; node = node->GetNext(), index++ )
518 wxToolBarToolBase *tool = node->GetData();
519 if ( !tool->IsControl() )
522 wxControl *control = tool->GetControl();
524 wxSize size = control->GetSize();
526 // the position of the leftmost controls corner
529 // note that we use TB_GETITEMRECT and not TB_GETRECT because the
530 // latter only appeared in v4.70 of comctl32.dll
532 if ( !SendMessage(GetHwnd(), TB_GETITEMRECT,
533 index, (LPARAM)(LPRECT)&r) )
535 wxLogLastError("TB_GETITEMRECT");
538 // TB_SETBUTTONINFO message is only supported by comctl32.dll 4.71+
539 #if defined(_WIN32_IE) && (_WIN32_IE >= 0x400 )
540 // available in headers, now check whether it is available now
542 if ( wxTheApp->GetComCtl32Version() >= 471 )
544 // set the (underlying) separators width to be that of the
547 tbbi.cbSize = sizeof(tbbi);
548 tbbi.dwMask = TBIF_SIZE;
550 if ( !SendMessage(GetHwnd(), TB_SETBUTTONINFO,
551 tool->GetId(), (LPARAM)&tbbi) )
553 // the id is probably invalid?
554 wxLogLastError("TB_SETBUTTONINFO");
559 #endif // comctl32.dll 4.71
560 // TB_SETBUTTONINFO unavailable
562 // try adding several separators to fit the controls width
563 int widthSep = r.right - r.left;
569 tbb.fsState = TBSTATE_ENABLED;
570 tbb.fsStyle = TBSTYLE_SEP;
572 size_t nSeparators = size.x / widthSep;
573 for ( size_t nSep = 0; nSep < nSeparators; nSep++ )
575 if ( !SendMessage(GetHwnd(), TB_INSERTBUTTON,
576 index, (LPARAM)&tbb) )
578 wxLogLastError("TB_INSERTBUTTON");
584 // remember the number of separators we used - we'd have to
585 // delete all of them later
586 ((wxToolBarTool *)tool)->SetSeparatorsCount(nSeparators);
588 // adjust the controls width to exactly cover the separators
589 control->SetSize((nSeparators + 1)*widthSep, -1);
592 // and position the control itself correctly vertically
593 int height = r.bottom - r.top;
594 int diff = height - size.y;
597 // the control is too high, resize to fit
598 control->SetSize(-1, height - 2);
603 control->Move(left == -1 ? r.left : left, r.top + (diff + 1) / 2);
606 // the max index is the "real" number of buttons - i.e. counting even the
607 // separators which we added just for aligning the controls
612 if ( m_maxRows == 0 )
614 // if not set yet, only one row
618 else if ( m_nButtons > 0 ) // vertical non empty toolbar
620 if ( m_maxRows == 0 )
622 // if not set yet, have one column
630 // ----------------------------------------------------------------------------
632 // ----------------------------------------------------------------------------
634 bool wxToolBar::OS2Command(
639 wxToolBarToolBase
* pTool
= FindById((int)nId
);
645 if (pTool->CanBeToggled())
647 LRESULT state = ::SendMessage(GetHwnd(), TB_GETSTATE, id, 0);
648 tool->SetToggle((state & TBSTATE_CHECKED) != 0);
651 bool toggled = tool->IsToggled();
653 // OnLeftClick() can veto the button state change - for buttons which may
654 // be toggled only, of couse
655 if ( !OnLeftClick((int)id, toggled) && tool->CanBeToggled() )
659 tool->SetToggle(toggled);
661 ::SendMessage(GetHwnd(), TB_CHECKBUTTON, id, MAKELONG(toggled, 0));
667 bool wxToolBar::OS2OnNotify(
675 // First check if this applies to us
676 NMHDR *hdr = (NMHDR *)lParam;
678 // the tooltips control created by the toolbar is sometimes Unicode, even
679 // in an ANSI application - this seems to be a bug in comctl32.dll v5
680 int code = (int)hdr->code;
681 if ( (code != TTN_NEEDTEXTA) && (code != TTN_NEEDTEXTW) )
684 HWND toolTipWnd = (HWND)::SendMessage((HWND)GetHWND(), TB_GETTOOLTIPS, 0, 0);
685 if ( toolTipWnd != hdr->hwndFrom )
688 LPTOOLTIPTEXT ttText = (LPTOOLTIPTEXT)lParam;
689 int id = (int)ttText->hdr.idFrom;
691 wxToolBarToolBase *tool = FindById(id);
695 const wxString& help = tool->GetShortHelp();
697 if ( !help.IsEmpty() )
699 if ( code == TTN_NEEDTEXTA )
701 ttText->lpszText = (wxChar *)help.c_str();
703 #if (_WIN32_IE >= 0x0300)
706 // FIXME this is a temp hack only until I understand better what
707 // must be done in both ANSI and Unicode builds
709 size_t lenAnsi = help.Len();
711 // MetroWerks doesn't like calling mbstowcs with NULL argument
712 size_t lenUnicode = 2*lenAnsi;
714 size_t lenUnicode = mbstowcs(NULL, help, lenAnsi);
717 // using the pointer of right type avoids us doing all sorts of
718 // pointer arithmetics ourselves
719 wchar_t *dst = (wchar_t *)ttText->szText,
720 *pwz = new wchar_t[lenUnicode + 1];
721 mbstowcs(pwz, help, lenAnsi + 1);
722 memcpy(dst, pwz, lenUnicode*sizeof(wchar_t));
724 // put the terminating _wide_ NUL
729 #endif // _WIN32_IE >= 0x0300
732 // For backward compatibility...
733 OnMouseEnter(tool->GetId());
738 // ----------------------------------------------------------------------------
740 // ----------------------------------------------------------------------------
742 void wxToolBar::SetToolBitmapSize(
746 wxToolBarBase::SetToolBitmapSize(rSize
);
748 // ::SendMessage(GetHwnd(), TB_SETBITMAPSIZE, 0, MAKELONG(size.x, size.y));
751 void wxToolBar::SetRows(
755 if (nRows
== m_maxRows
)
757 // avoid resizing the frame uselessly
762 // TRUE in wParam means to create at least as many rows, FALSE -
765 ::SendMessage(GetHwnd(), TB_SETROWS,
766 MAKEWPARAM(nRows, !(GetWindowStyle() & wxTB_VERTICAL)),
775 // The button size is bigger than the bitmap size
776 wxSize
wxToolBar::GetToolSize() const
780 // TB_GETBUTTONSIZE is supported from version 4.70
781 #if defined(_WIN32_IE) && (_WIN32_IE >= 0x300 )
782 if ( wxTheApp->GetComCtl32Version() >= 470 )
784 DWORD dw = ::SendMessage(GetHwnd(), TB_GETBUTTONSIZE, 0, 0);
786 return wxSize(LOWORD(dw), HIWORD(dw));
789 #endif // comctl32.dll 4.70+
792 return wxSize(m_defaultWidth + 8, m_defaultHeight + 7);
795 return wxSize(m_defaultWidth
+ 8, m_defaultHeight
+ 7);
798 wxToolBarToolBase
*wxToolBar::FindToolForPosition(
808 int nIndex
= 0; //(int)::SendMessage(GetHwnd(), TB_HITTEST, 0, (LPARAM)&pt);
811 // it's a separator or there is no tool at all there
812 return (wxToolBarToolBase
*)NULL
;
814 return(m_tools
.Item((size_t)nIndex
)->GetData());
817 void wxToolBar::UpdateSize()
819 // we must refresh the frame after the toolbar size (possibly) changed
820 wxFrame
* pFrame
= wxDynamicCast(GetParent(), wxFrame
);
824 // don't change the size, we just need to generate a WM_SIZE
828 if ( !GetWindowRect(GetHwndOf(frame), &r) )
830 wxLogLastError(_T("GetWindowRect"));
833 (void)::SendMessage(GetHwndOf(frame), WM_SIZE, SIZE_RESTORED,
834 MAKELPARAM(r.right - r.left, r.bottom - r.top));
839 // ----------------------------------------------------------------------------
841 // ----------------------------------------------------------------------------
843 void wxToolBar::DoEnableTool(
844 wxToolBarToolBase
* pTool
850 ::SendMessage(GetHwnd(), TB_ENABLEBUTTON,
851 (WPARAM)tool->GetId(), (LPARAM)MAKELONG(enable, 0));
855 void wxToolBar::DoToggleTool(
856 wxToolBarToolBase
* pTool
862 ::SendMessage(GetHwnd(), TB_CHECKBUTTON,
863 (WPARAM)tool->GetId(), (LPARAM)MAKELONG(toggle, 0));
867 void wxToolBar::DoSetToggle(
868 wxToolBarToolBase
* pTool
872 // VZ: AFAIK, the button has to be created either with TBSTYLE_CHECK or
873 // without, so we really need to delete the button and recreate it here
874 wxFAIL_MSG( _T("not implemented") );
877 // ----------------------------------------------------------------------------
879 // ----------------------------------------------------------------------------
881 // Responds to colour changes, and passes event on to children.
882 void wxToolBar::OnSysColourChanged(
883 wxSysColourChangedEvent
& rEvent
888 m_backgroundColour = wxColour(GetRValue(GetSysColor(COLOR_BTNFACE)),
889 GetGValue(GetSysColor(COLOR_BTNFACE)), GetBValue(GetSysColor(COLOR_BTNFACE)));
897 // Propagate the event to the non-top-level children
898 wxWindow::OnSysColourChanged(rEvent
);
901 void wxToolBar::OnMouseEvent(
905 if (rEvent
.RightDown())
907 // For now, we don't have an id. Later we could
908 // try finding the tool.
909 OnRightClick( (int)-1
920 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
;