// Call GUI here:
my_window->DrawSomething();
-
+
wxMutexGuiLeave();
}
\end{verbatim}
\membersection{::wxGetNumberFromUser}\label{wxgetnumberfromuser}
+\func{wxColour}{wxGetColourFromUser}{\param{wxWindow *}{parent}, \parent{const wxColour\& }{colInit}}
+
+Shows the colour selection dialog and returns the colour selected by user or
+invalid colour (use \helpref{wxColour::Ok}{wxcolourok} to test whether a colour
+is valid) if the dialog was cancelled.
+
+\wxheading{Parameters}
+
+\docparam{parent}{The parent window for the colour selection dialog}
+
+\docparam{colInit}{If given, this will be the colour initially selected in the dialog.}
+
+\wxheading{Include files}
+
+<wx/colordlg.h>
+
+\membersection{::wxGetNumberFromUser}\label{wxgetnumberfromuser}
+
\func{long}{wxGetNumberFromUser}{
\param{const wxString\& }{message},
\param{const wxString\& }{prompt},
This event class contains information about mouse events.
See \helpref{wxWindow::OnMouseEvent}{wxwindowonmouseevent}.
+{\bf NB: } Note that under Windows mouse enter and leave events are not natively supported
+by the system but are generated by wxWindows itself. This has several
+drawbacks: the LEAVE\_WINDOW event might be received some time after the mouse
+left the window and the state variables for it may have changed during this
+time.
+
\wxheading{Derived from}
\helpref{wxEvent}{wxevent}
/////////////////////////////////////////////////////////////////////////////
-// Name: controls.cpp
+// Name: text.cpp
// Purpose: TextCtrl wxWindows sample
// Author: Robert Roebling
// Modified by:
// RCS-ID: $Id$
-// Copyright: (c) Robert Roebling, Julian Smart
+// Copyright: (c) Robert Roebling, Julian Smart, Vadim Zeitlin
// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
void OnKeyUp(wxKeyEvent& event);
void OnChar(wxKeyEvent& event);
void OnText(wxCommandEvent& event);
+ void OnMouseEvent(wxMouseEvent& event);
bool m_hasCapture;
EVT_KEY_UP(MyTextCtrl::OnKeyUp)
EVT_CHAR(MyTextCtrl::OnChar)
EVT_TEXT(-1, MyTextCtrl::OnText)
+ EVT_MOUSE_EVENTS(MyTextCtrl::OnMouseEvent)
END_EVENT_TABLE()
void MyTextCtrl::LogEvent(const wxChar *name, wxKeyEvent& event) const
}
+void MyTextCtrl::OnMouseEvent(wxMouseEvent& ev)
+{
+ if ( !ev.Moving() )
+ {
+ wxString msg;
+ if ( ev.Entering() )
+ {
+ msg = _T("Mouse entered the window");
+ }
+ else if ( ev.Leaving() )
+ {
+ msg = _T("Mouse left the window");
+ }
+ else
+ {
+ // click event
+ wxString button;
+ bool dbl, up;
+ if ( ev.LeftDown() || ev.LeftUp() || ev.LeftDClick() )
+ {
+ button = _T("Left");
+ dbl = ev.LeftDClick();
+ up = ev.LeftUp();
+ }
+ else if ( ev.MiddleDown() || ev.MiddleUp() || ev.MiddleDClick() )
+ {
+ button = _T("Middle");
+ dbl = ev.MiddleDClick();
+ up = ev.MiddleUp();
+ }
+ else if ( ev.RightDown() || ev.RightUp() || ev.RightDClick() )
+ {
+ button = _T("Right");
+ dbl = ev.RightDClick();
+ up = ev.RightUp();
+ }
+ else
+ {
+ wxLogStatus(_T("Unknown mouse event"));
+ return;
+ }
+
+ msg.Printf(_T("%s mouse button %s"),
+ button.c_str(),
+ dbl ? _T("double clicked")
+ : up ? _T("released") : _T("clicked"));
+ }
+
+ msg << _T(" at (") << ev.GetX() << _T(", ") << ev.GetY() << _T(") ")
+ << _T("Flags: ")
+ << GetChar( ev.LeftDown(), _T('1') )
+ << GetChar( ev.MiddleDown(), _T('2') )
+ << GetChar( ev.RightDown(), _T('3') )
+ << GetChar( ev.ControlDown(), _T('C') )
+ << GetChar( ev.AltDown(), _T('A') )
+ << GetChar( ev.ShiftDown(), _T('S') )
+ << GetChar( ev.MetaDown(), _T('M') );
+
+ wxLogMessage(msg);
+ }
+ //else: we're not interested in mouse move events
+}
+
void MyTextCtrl::OnText(wxCommandEvent& event)
{
MyTextCtrl *win = (MyTextCtrl *)event.GetEventObject();
}
}
+ delete [] data;
+ delete [] result_data;
+
return rotated;
}
// event handlers
void OnOk(wxCommandEvent& event);
void OnDetails(wxCommandEvent& event);
+ void OnListSelect(wxListEvent& event);
private:
// the data for the listctrl
BEGIN_EVENT_TABLE(wxLogDialog, wxDialog)
EVT_BUTTON(wxID_OK, wxLogDialog::OnOk)
EVT_BUTTON(wxID_MORE, wxLogDialog::OnDetails)
+ EVT_LIST_ITEM_SELECTED(-1, wxLogDialog::OnListSelect)
END_EVENT_TABLE()
#endif // wxUSE_LOG_DIALOG
const wxArrayLong& times,
const wxString& caption,
long style)
- : wxDialog(parent, -1, caption ),
- m_messages(messages), m_severity(severity), m_times(times)
+ : wxDialog(parent, -1, caption )
{
+ size_t count = messages.GetCount();
+ m_messages.Alloc(count);
+ m_severity.Alloc(count);
+ m_times.Alloc(count);
+
+ for ( size_t n = 0; n < count; n++ )
+ {
+ wxString msg = messages[n];
+ do
+ {
+ m_messages.Add(msg.BeforeFirst(_T('\n')));
+ msg = msg.AfterFirst(_T('\n'));
+
+ m_severity.Add(severity[n]);
+ m_times.Add(times[n]);
+ }
+ while ( !!msg );
+ }
+
m_showingDetails = FALSE; // not initially
m_listctrl = (wxListCtrl *)NULL;
btnOk->SetFocus();
- if ( m_messages.GetCount() == 1 )
+ if ( count == 1 )
{
// no details... it's easier to disable a button than to change the
// dialog layout depending on whether we have details or not
Centre();
}
+void wxLogDialog::OnListSelect(wxListEvent& event)
+{
+ // we can't just disable the control because this looks ugly under Windows
+ // (wrong bg colour, no scrolling...), but we still want to disable
+ // selecting items - it makes no sense here
+ m_listctrl->SetItemState(event.GetItem(), 0, wxLIST_STATE_SELECTED);
+}
+
void wxLogDialog::OnOk(wxCommandEvent& WXUNUSED(event))
{
EndModal(wxID_OK);
wxDefaultPosition, wxDefaultSize,
wxSUNKEN_BORDER |
wxLC_REPORT |
- wxLC_NO_HEADER );
+ wxLC_NO_HEADER |
+ wxLC_SINGLE_SEL);
m_listctrl->InsertColumn(0, _("Message"));
m_listctrl->InsertColumn(1, _("Time"));
static const double M_PI = 3.14159265358979323846;
#endif // M_PI
+// ROPs which don't have standard names (see "Ternary Raster Operations" in the
+// MSDN docs for how this and other numbers in wxDC::Blit() are obtained)
+#define DSTCOPY 0x00AA0029 // a.k.a. NOP operation
+
// ---------------------------------------------------------------------------
// private functions
// ---------------------------------------------------------------------------
HDC hdcMem = ::CreateCompatibleDC(GetHdc());
::SelectObject(hdcMem, GetHbitmapOf(bmp));
- // this will only work if the transparent part of our bitmap is black
- // because it is combined with the destination rectangle using OR, so
- // it won't be really transparent otherwise - I don't know what to do
- // about it, may be use MAKEROP4(SRCCOPY, DSTINVERT) twice? Or create a
- // copy of the bitmap with the transparent part replaced with black
- // pixels?
-
- // GRG: now this works regardless of what the source bitmap
- // contains in the area which is to be transparent.
- //
+ // use MaskBlt() with ROP which doesn't do anything to dst in the mask
+ // points
bool ok = ::MaskBlt(GetHdc(), x, y, width, height,
hdcMem, 0, 0,
hbmpMask, 0, 0,
- MAKEROP4(SRCCOPY, 0x00AA0029)) != 0;
+ MAKEROP4(SRCCOPY, DSTCOPY)) != 0;
::DeleteDC(hdcMem);
if ( !ok )
#endif // Win32
{
- // VZ: this is incorrect, Blit() doesn't (and can't) draw
- // transparently, but it's still better than nothing at all
- // GRG: Blit() *should* draw transparently when there is a mask
-
- // Rather than reproduce wxDC::Blit, let's do it at the wxWin API level
+ // Rather than reproduce wxDC::Blit, let's do it at the wxWin API
+ // level
wxMemoryDC memDC;
memDC.SelectObject(bmp);
switch (m_logicalFunction)
{
+ case wxCLEAR: rop = R2_BLACK; break;
case wxXOR: rop = R2_XORPEN; break;
case wxINVERT: rop = R2_NOT; break;
case wxOR_REVERSE: rop = R2_MERGEPENNOT; break;
case wxAND_REVERSE: rop = R2_MASKPENNOT; break;
- case wxCLEAR: rop = R2_WHITE; break;
- case wxSET: rop = R2_BLACK; break;
- case wxOR_INVERT: rop = R2_MERGENOTPEN; break;
+ case wxCOPY: rop = R2_COPYPEN; break;
case wxAND: rop = R2_MASKPEN; break;
- case wxOR: rop = R2_MERGEPEN; break;
- case wxEQUIV: rop = R2_NOTXORPEN; break;
- case wxNAND: rop = R2_NOTMASKPEN; break;
case wxAND_INVERT: rop = R2_MASKNOTPEN; break;
- case wxCOPY: rop = R2_COPYPEN; break;
case wxNO_OP: rop = R2_NOP; break;
- case wxSRC_INVERT: rop = R2_NOTCOPYPEN; break;
case wxNOR: rop = R2_NOTMERGEPEN; break;
+ case wxEQUIV: rop = R2_NOTXORPEN; break;
+ case wxSRC_INVERT: rop = R2_NOTCOPYPEN; break;
+ case wxOR_INVERT: rop = R2_MERGENOTPEN; break;
+ case wxNAND: rop = R2_NOTMASKPEN; break;
+ case wxOR: rop = R2_MERGEPEN; break;
+ case wxSET: rop = R2_WHITE; break;
+
default:
wxFAIL_MSG( wxT("unsupported logical function") );
return;
case wxNAND: dwRop = 0x007700E6; break;
case wxAND_INVERT: dwRop = 0x00220326; break;
case wxCOPY: dwRop = SRCCOPY; break;
- case wxNO_OP: dwRop = 0x00AA0029; break;
+ case wxNO_OP: dwRop = DSTCOPY; break;
case wxSRC_INVERT: dwRop = NOTSRCCOPY; break;
case wxNOR: dwRop = NOTSRCCOPY; break;
default:
if (useMask)
{
#ifdef __WIN32__
- // prepare the mask bitmap
- HBITMAP hbmpMask = wxInvertMask((HBITMAP)mask->GetMaskBitmap());
-
- // select the correct brush: the current one by default, background one
- // if none
- HBRUSH hbrNew;
- if ( m_brush.Ok() )
- {
- hbrNew = (HBRUSH)m_brush.GetResourceHandle();
- }
- else if ( m_backgroundBrush.Ok() )
- {
- hbrNew = (HBRUSH)m_backgroundBrush.GetResourceHandle();
- }
- else
- {
- hbrNew = 0;
- }
-
- HGDIOBJ hbrOld = hbrNew ? ::SelectObject(GetHdc(), hbrNew) : 0;
-
// we want the part of the image corresponding to the mask to be
- // transparent, i.e. do PATCOPY there and apply dwRop elsewhere
-
- // GRG: PATCOPY is not transparent, as can be seen when blitting
- // over a pattern: the 'transparent' area would be filled
- // with the selected colour. We should use NOP instead, or
- // do MaskBlt + BitBlt.
- //
+ // transparent, so use "DSTCOPY" ROP for the mask points (the usual
+ // meaning of fg and bg is inverted which corresponds to wxWin notion
+ // of the mask which is also contrary to the Windows one)
success = ::MaskBlt(GetHdc(), xdest, ydest, width, height,
GetHdcOf(*source), xsrc, ysrc,
- hbmpMask, 0, 0,
- MAKEROP4(0x00AA0029, dwRop)) != 0;
-
- if ( hbrNew )
- {
- (void)::SelectObject(GetHdc(), hbrOld);
- }
-
- ::DeleteObject(hbmpMask);
+ (HBITMAP)mask->GetMaskBitmap(), 0, 0,
+ MAKEROP4(dwRop, DSTCOPY)) != 0;
if ( !success )
#endif // Win32
void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win);
wxWindow *wxFindWinFromHandle(WXHWND hWnd);
+// this magical function is used to translate VK_APPS key presses to right
+// mouse clicks
+static void TranslateKbdEventToMouse(wxWindow *win, int *x, int *y, WPARAM *flags);
+
// ---------------------------------------------------------------------------
// event tables
// ---------------------------------------------------------------------------
// click because both usually pop up a context menu
case VK_APPS:
{
- // construct the key mask
- WPARAM fwKeys = MK_RBUTTON;
- if ( (::GetKeyState(VK_CONTROL) & 0x100) != 0 )
- fwKeys |= MK_CONTROL;
- if ( (::GetKeyState(VK_SHIFT) & 0x100) != 0 )
- fwKeys |= MK_SHIFT;
-
- // simulate right mouse button click
- DWORD dwPos = ::GetMessagePos();
- int x = GET_X_LPARAM(dwPos),
- y = GET_Y_LPARAM(dwPos);
-
- ScreenToClient(&x, &y);
- processed = HandleMouseEvent(WM_RBUTTONDOWN, x, y, fwKeys);
+ WPARAM flags;
+ int x, y;
+
+ TranslateKbdEventToMouse(this, &x, &y, &flags);
+ processed = HandleMouseEvent(WM_RBUTTONDOWN, x, y, flags);
}
break;
#endif // VK_APPS
case WM_SYSKEYUP:
case WM_KEYUP:
- processed = HandleKeyUp((WORD) wParam, lParam);
+#ifdef VK_APPS
+ // special case of VK_APPS: treat it the same as right mouse button
+ if ( wParam == VK_APPS )
+ {
+ WPARAM flags;
+ int x, y;
+
+ TranslateKbdEventToMouse(this, &x, &y, &flags);
+ processed = HandleMouseEvent(WM_RBUTTONUP, x, y, flags);
+ }
+ else
+#endif // VK_APPS
+ {
+ processed = HandleKeyUp((WORD) wParam, lParam);
+ }
break;
case WM_SYSCHAR:
}
}
#endif //__WXDEBUG__
+
+static void TranslateKbdEventToMouse(wxWindow *win, int *x, int *y, WPARAM *flags)
+{
+ // construct the key mask
+ WPARAM& fwKeys = *flags;
+
+ fwKeys = MK_RBUTTON;
+ if ( (::GetKeyState(VK_CONTROL) & 0x100) != 0 )
+ fwKeys |= MK_CONTROL;
+ if ( (::GetKeyState(VK_SHIFT) & 0x100) != 0 )
+ fwKeys |= MK_SHIFT;
+
+ // simulate right mouse button click
+ DWORD dwPos = ::GetMessagePos();
+ *x = GET_X_LPARAM(dwPos);
+ *y = GET_Y_LPARAM(dwPos);
+
+ win->ScreenToClient(x, y);
+}