Added wxHelpEvent, wxContextHelp (MSW only so far), modified help sample

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@8271 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Julian Smart 2000-09-06 09:45:24 +00:00
parent ceae98ef7a
commit b96340e6f4
12 changed files with 323 additions and 2 deletions

View File

@ -39,6 +39,8 @@ the list wraps, unlike a wxListBox.}
\twocolitem{\windowstyle{wxLC\_SINGLE\_SEL}}{Single selection.}
\twocolitem{\windowstyle{wxLC\_SORT\_ASCENDING}}{Sort in ascending order (must still supply a comparison callback in SortItems.}
\twocolitem{\windowstyle{wxLC\_SORT\_DESCENDING}}{Sort in descending order (must still supply a comparison callback in SortItems.}
\twocolitem{\windowstyle{wxLC\_HRULES}}{Draws light horizontal rules between rows in report mode.}
\twocolitem{\windowstyle{wxLC\_VRULES}}{Draws light vertical rules between columns in report mode.}
\end{twocollist}
See also \helpref{window styles overview}{windowstyles}.

View File

@ -917,6 +917,10 @@ enum wxStretch
// Add for normal Windows frame behaviour
#define wxFRAME_FLOAT_ON_PARENT 0x0020
// Context-sensitive help
#define wxFRAME_EX_CONTEXTHELP 0x00000004
#define wxDIALOG_EX_CONTEXTHELP 0x00000004
/*
* MDI parent frame style flags
* Can overlap with some of the above.

View File

@ -291,6 +291,9 @@ enum
wxEVT_PLOT_END_TITLE_EDIT = wxEVT_FIRST + 1025,
wxEVT_PLOT_AREA_CREATE = wxEVT_FIRST + 1026,
/* Help events */
wxEVT_HELP = wxEVT_FIRST + 1050,
wxEVT_USER_FIRST = wxEVT_FIRST + 2000
};
@ -1400,6 +1403,26 @@ public:
wxWindow *GetWindow() const { return (wxWindow *)GetEventObject(); }
};
/*
wxEVT_HELP
Sent when the user clicks on a window in context-help mode.
The cursor position is in screen coordinates.
*/
class WXDLLEXPORT wxHelpEvent : public wxCommandEvent
{
DECLARE_DYNAMIC_CLASS(wxHelpEvent)
public:
wxHelpEvent(wxEventType type = wxEVT_NULL, wxWindowID id = 0, const wxPoint& pt = wxPoint(0, 0))
{ m_eventType = type; m_id = id; m_pos = pt; }
const wxPoint& GetPosition() const { return m_pos; }
void SetPosition(const wxPoint& pos) { m_pos = pos; }
wxPoint m_pos;
};
#endif // wxUSE_GUI
// Idle event
@ -1603,6 +1626,7 @@ typedef void (wxEvtHandler::*wxWindowCreateEventFunction)(wxWindowCreateEvent&);
typedef void (wxEvtHandler::*wxWindowDestroyEventFunction)(wxWindowDestroyEvent&);
typedef void (wxEvtHandler::*wxSetCursorEventFunction)(wxSetCursorEvent&);
typedef void (wxEvtHandler::*wxNotifyEventFunction)(wxNotifyEvent&);
typedef void (wxEvtHandler::*wxHelpEventFunction)(wxHelpEvent&);
#endif // wxUSE_GUI
// N.B. In GNU-WIN32, you *have* to take the address of a member function
@ -1818,6 +1842,13 @@ const wxEventTableEntry theClass::sm_eventTableEntries[] = { \
#define EVT_UPDATE_UI_RANGE(id1, id2, func) \
{ wxEVT_UPDATE_UI, id1, id2, (wxObjectEventFunction)(wxEventFunction)(wxUpdateUIEventFunction)&func, (wxObject *) NULL },
// Help events
#define EVT_HELP(id, func) \
{ wxEVT_HELP, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxHelpEventFunction) & func, (wxObject *) NULL },
#define EVT_HELP_RANGE(id1, id2, func) \
{ wxEVT_HELP, id1, id2, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxHelpEventFunction) & func, (wxObject *) NULL },
// ----------------------------------------------------------------------------
// Global data
// ----------------------------------------------------------------------------

View File

@ -76,6 +76,35 @@ public:
virtual void OnQuit(void) {};
};
/*
* wxContextHelp
* Invokes context-sensitive help. When the user
* clicks on a window, a wxEVT_HELP event will be sent to that
* window for the application to display help for.
*/
class WXDLLEXPORT wxContextHelp: public wxObject
{
DECLARE_DYNAMIC_CLASS(wxContextHelp)
public:
wxContextHelp(wxWindow* win = NULL, bool beginHelp = TRUE);
~wxContextHelp();
bool BeginContextHelp(wxWindow* win);
bool EndContextHelp();
bool EventLoop(const wxCursor& cursor, wxWindow* win);
bool DispatchEvent(wxWindow* win, const wxPoint& pt);
#ifdef __WXMSW__
bool ProcessHelpMessage(WXMSG* wxmsg, const wxCursor& cursor, wxWindow* win);
#endif
protected:
bool m_inHelp;
};
#endif // wxUSE_HELP
#endif
// _WX_HELPBASEH__

View File

@ -113,6 +113,9 @@ public:
void OnAdvancedHtmlHelp(wxCommandEvent& event);
void OnMSHtmlHelp(wxCommandEvent& event);
void OnContextHelp(wxHelpEvent& event);
void OnShowContextHelp(wxCommandEvent& event);
void ShowHelp(int commandId, wxHelpControllerBase& helpController);
private:
@ -147,6 +150,7 @@ enum
HelpDemo_Help_Functions,
HelpDemo_Help_Help,
HelpDemo_Help_Search,
HelpDemo_Help_ContextHelp,
HelpDemo_Html_Help_Index,
HelpDemo_Html_Help_Classes,
@ -187,6 +191,9 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(HelpDemo_Help_Functions, MyFrame::OnHelp)
EVT_MENU(HelpDemo_Help_Help, MyFrame::OnHelp)
EVT_MENU(HelpDemo_Help_Search, MyFrame::OnHelp)
EVT_MENU(HelpDemo_Help_ContextHelp, MyFrame::OnShowContextHelp)
EVT_HELP(-1, MyFrame::OnContextHelp)
EVT_MENU(HelpDemo_Html_Help_Index, MyFrame::OnHtmlHelp)
EVT_MENU(HelpDemo_Html_Help_Classes, MyFrame::OnHtmlHelp)
@ -310,6 +317,7 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
menuFile->Append(HelpDemo_Help_Index, "&Help Index...");
menuFile->Append(HelpDemo_Help_Classes, "&Help on Classes...");
menuFile->Append(HelpDemo_Help_Functions, "&Help on Functions...");
menuFile->Append(HelpDemo_Help_ContextHelp, "&Context Help...");
menuFile->Append(HelpDemo_Help_Help, "&About Help Demo...");
menuFile->Append(HelpDemo_Help_Search, "&Search help...");
#if USE_HTML_HELP
@ -384,6 +392,21 @@ void MyFrame::OnHelp(wxCommandEvent& event)
ShowHelp(event.GetId(), m_help);
}
void MyFrame::OnShowContextHelp(wxCommandEvent& event)
{
// This starts context help mode, then the user
// clicks on a window to send a help message
wxContextHelp contextHelp(this);
}
void MyFrame::OnContextHelp(wxHelpEvent& event)
{
// In a real app, if we didn't recognise this ID, we should call event.Skip()
wxString msg;
msg.Printf(wxT("We should now display help for window %d"), event.GetId());
wxMessageBox(msg);
}
void MyFrame::OnHtmlHelp(wxCommandEvent& event)
{
#if USE_HTML_HELP && USE_OLD_HTML_HELP

View File

@ -82,6 +82,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxIdleEvent, wxEvent)
IMPLEMENT_DYNAMIC_CLASS(wxQueryNewPaletteEvent, wxEvent)
IMPLEMENT_DYNAMIC_CLASS(wxWindowCreateEvent, wxEvent)
IMPLEMENT_DYNAMIC_CLASS(wxWindowDestroyEvent, wxEvent)
IMPLEMENT_DYNAMIC_CLASS(wxHelpEvent, wxCommandEvent)
#endif // wxUSE_GUI
const wxEventTable *wxEvtHandler::GetEventTable() const

View File

@ -26,8 +26,196 @@
#include "wx/helpbase.h"
#ifdef __WXMSW__
#include "wx/msw/private.h"
#endif
#if wxUSE_HELP
IMPLEMENT_CLASS(wxHelpControllerBase, wxObject)
/*
* Invokes context-sensitive help
*/
IMPLEMENT_DYNAMIC_CLASS(wxContextHelp, wxObject)
wxContextHelp::wxContextHelp(wxWindow* win, bool beginHelp)
{
m_inHelp = FALSE;
if (beginHelp)
BeginContextHelp(win);
}
wxContextHelp::~wxContextHelp()
{
if (m_inHelp)
EndContextHelp();
}
bool wxContextHelp::BeginContextHelp(wxWindow* win)
{
if (!win)
win = wxTheApp->GetTopWindow();
if (!win)
return FALSE;
wxCursor cursor(wxCURSOR_QUESTION_ARROW);
wxSetCursor(cursor);
win->CaptureMouse();
EventLoop(cursor, win);
win->ReleaseMouse();
return TRUE;
}
bool wxContextHelp::EndContextHelp()
{
m_inHelp = FALSE;
return TRUE;
}
bool wxContextHelp::EventLoop(const wxCursor& cursor, wxWindow* win)
{
#ifdef __WXMSW__
m_inHelp = TRUE;
while ( m_inHelp )
{
MSG msg;
if (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (!ProcessHelpMessage((WXMSG*) & msg, cursor, win))
{
m_inHelp = FALSE;
}
}
else
{
wxTheApp->ProcessIdle();
}
}
return TRUE;
#else
return FALSE;
#endif
}
#ifdef __WXMSW__
bool wxContextHelp::ProcessHelpMessage(WXMSG* wxmsg, const wxCursor& cursor, wxWindow* winInQuestion)
{
MSG& msg = * (MSG*) wxmsg;
if (msg.message == WM_KEYDOWN || msg.wParam == VK_ESCAPE)
{
PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE);
return FALSE;
}
if (msg.message == WM_CAPTURECHANGED)
{
PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE);
return FALSE;
}
if (msg.message == WM_ACTIVATE)
{
PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE);
return FALSE;
}
if ((msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST))
// || (msg.message >= WM_NCMOUSEFIRST && msg.message <= WM_NCMOUSELAST))
{
wxSetCursor(cursor);
HWND hWndHit = ::WindowFromPoint(msg.pt);
wxWindow* win = wxFindWinFromHandle((WXHWND) hWndHit) ;
HWND hWnd = hWndHit;
// Try to find a window with a wxWindow associated with it
while (!win && (hWnd != 0))
{
hWnd = ::GetParent(hWnd);
win = wxFindWinFromHandle((WXHWND) hWnd) ;
}
if (win)
{
// It's a wxWindows window
if (msg.message != WM_LBUTTONDOWN)
{
// Hit one of our owned windows -- eat the message.
PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE);
return TRUE;
}
int iHit = (int)::SendMessage(hWndHit, WM_NCHITTEST, 0,
MAKELONG(msg.pt.x, msg.pt.y));
if (iHit == HTMENU || iHit == HTSYSMENU)
{
// Eat this message, send the event and return
PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE);
DispatchEvent(win, wxPoint(msg.pt.x, msg.pt.y));
return FALSE;
}
else if (iHit == HTCLIENT)
{
PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE);
DispatchEvent(win, wxPoint(msg.pt.x, msg.pt.y));
return FALSE;
}
else
{
PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE);
return FALSE;
}
}
else
{
// Someone else's message
if (PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
return TRUE;
}
}
else
{
// allow all other messages to go through (capture still set)
if (PeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE))
DispatchMessage(&msg);
return TRUE;
}
return TRUE;
}
#endif
// Dispatch the help event to the relevant window
bool wxContextHelp::DispatchEvent(wxWindow* win, const wxPoint& pt)
{
wxWindow* subjectOfHelp = win;
bool eventProcessed = FALSE;
while (subjectOfHelp && !eventProcessed)
{
wxHelpEvent helpEvent(wxEVT_HELP, subjectOfHelp->GetId(), pt) ;
helpEvent.SetEventObject(this);
eventProcessed = win->GetEventHandler()->ProcessEvent(helpEvent);
// Go up the window hierarchy until the event is handled (or not).
// I.e. keep submitting ancestor windows until one is recognised
// by the app code that processes the ids and displays help.
subjectOfHelp = subjectOfHelp->GetParent();
}
return eventProcessed;
}
#endif // wxUSE_HELP

View File

@ -46,7 +46,14 @@ wxSplashScreen::wxSplashScreen(const wxBitmap& bitmap, long splashStyle, int mil
m_window = new wxSplashScreenWindow(bitmap, this, -1, pos, size, wxNO_BORDER);
SetClientSize(bitmap.GetWidth(), bitmap.GetHeight());
// For some reason, we need to make the client size a couple of pixels
// bigger for all of the bitmap to show.
#ifdef __WXMSW__
int fudge = 2;
#else
int fudge = 0;
#endif
SetClientSize(bitmap.GetWidth()+fudge, bitmap.GetHeight()+fudge);
if (m_splashStyle & wxSPLASH_CENTRE_ON_PARENT)
CentreOnParent();

View File

@ -289,6 +289,7 @@ wxCursor::wxCursor(int cursor_type)
}
case wxCURSOR_QUESTION_ARROW:
{
// refData->m_hCursor = (WXHCURSOR) LoadImage(wxGetInstance(), wxT("wxCURSOR_QARROW"), IMAGE_CURSOR, 16, 16, LR_MONOCHROME);
refData->m_hCursor = (WXHCURSOR) LoadCursor(wxGetInstance(), wxT("wxCURSOR_QARROW"));
break;
}

View File

@ -152,6 +152,8 @@ bool wxDialog::Create(wxWindow *parent, wxWindowID id,
WXDWORD extendedStyle = MakeExtendedStyle(m_windowStyle);
if (m_windowStyle & wxSTAY_ON_TOP)
extendedStyle |= WS_EX_TOPMOST;
if (m_exStyle & wxFRAME_EX_CONTEXTHELP)
extendedStyle |= WS_EX_CONTEXTHELP;
// Allows creation of dialogs with & without captions under MSWindows,
// resizeable or not (but a resizeable dialog always has caption -

View File

@ -680,6 +680,9 @@ bool wxFrame::MSWCreate(int id, wxWindow *parent, const wxChar *wclass, wxWindow
if (style & wxSTAY_ON_TOP)
extendedStyle |= WS_EX_TOPMOST;
if (m_exStyle & wxFRAME_EX_CONTEXTHELP)
extendedStyle |= WS_EX_CONTEXTHELP;
m_iconized = FALSE;
if ( !wxWindow::MSWCreate(id, parent, wclass, wx_win, title, x, y, width, height,
msflags, NULL, extendedStyle) )

View File

@ -2170,6 +2170,36 @@ long wxWindow::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
rc.result = TRUE;
}
break;
#ifdef __WIN32__
case WM_HELP:
{
HELPINFO* info = (HELPINFO*) lParam;
// Don't yet process menu help events, just windows
if (info->iContextType == HELPINFO_WINDOW)
{
wxWindow* subjectOfHelp = this;
bool eventProcessed = FALSE;
while (subjectOfHelp && !eventProcessed)
{
wxHelpEvent helpEvent(wxEVT_HELP, subjectOfHelp->GetId(), wxPoint(info->MousePos.x, info->MousePos.y) ) ; // info->iCtrlId);
helpEvent.SetEventObject(this);
eventProcessed = GetEventHandler()->ProcessEvent(helpEvent);
// Go up the window hierarchy until the event is handled (or not)
subjectOfHelp = subjectOfHelp->GetParent();
}
processed = eventProcessed;
}
else if (info->iContextType == HELPINFO_MENUITEM)
{
wxHelpEvent helpEvent(wxEVT_HELP, info->iCtrlId) ;
helpEvent.SetEventObject(this);
processed = GetEventHandler()->ProcessEvent(helpEvent);
}
else processed = FALSE;
break;
}
#endif
}
if ( !processed )
@ -3173,7 +3203,7 @@ void wxWindow::InitMouseEvent(wxMouseEvent& event, int x, int y, WXUINT flags)
event.m_leftDown = ((flags & MK_LBUTTON) != 0);
event.m_middleDown = ((flags & MK_MBUTTON) != 0);
event.m_rightDown = ((flags & MK_RBUTTON) != 0);
event.m_altDown = ::GetKeyState(VK_MENU) & 0x80000000;
event.m_altDown = (::GetKeyState(VK_MENU) & 0x80000000) != 0;
event.SetTimestamp(s_currentMsg.time);
event.m_eventObject = this;