525 lines
12 KiB
C++
525 lines
12 KiB
C++
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Crytek Engine Source File.
|
|
// Copyright (C), Crytek Studios, 2002.
|
|
// -------------------------------------------------------------------------
|
|
// File name: dynamichelpdialog.cpp
|
|
// Version: v1.00
|
|
// Created: 12/6/2003 by Timur.
|
|
// Compilers: Visual Studio.NET
|
|
// Description:
|
|
// -------------------------------------------------------------------------
|
|
// History:
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "DynamicHelpDialog.h"
|
|
#include "MainFrm.h"
|
|
|
|
|
|
#define HELP_FOLDER "Editor\\Help"
|
|
|
|
static HHOOK hMouseHook = 0;
|
|
static CDynamicHelpDialog *gDynamicHelpDialog = 0;
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
static LRESULT CALLBACK DynamicHelpMouseProc(
|
|
int nCode, // hook code
|
|
WPARAM wParam, // message identifier
|
|
LPARAM lParam // mouse coordinates
|
|
)
|
|
{
|
|
if (nCode >= 0)
|
|
{
|
|
if (gDynamicHelpDialog)
|
|
{
|
|
if (wParam == WM_MOUSEMOVE)
|
|
{
|
|
gDynamicHelpDialog->DisplayDynamicHelp();
|
|
}
|
|
else if (wParam == WM_LBUTTONDOWN)
|
|
{
|
|
// Check if also CTRL+ALT+SHIFT pressed.
|
|
GetAsyncKeyState(VK_MENU);
|
|
GetAsyncKeyState(VK_CONTROL);
|
|
GetAsyncKeyState(VK_SHIFT);
|
|
if (GetAsyncKeyState(VK_MENU) && GetAsyncKeyState(VK_CONTROL) && GetAsyncKeyState(VK_SHIFT))
|
|
{
|
|
gDynamicHelpDialog->EditItem();
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return CallNextHookEx( hMouseHook,nCode,wParam,lParam );
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
// CDynamicHelpDialog dialog
|
|
|
|
CDynamicHelpDialog* CDynamicHelpDialog::m_instance = 0;
|
|
|
|
void CDynamicHelpDialog::Open()
|
|
{
|
|
if (!m_instance)
|
|
{
|
|
m_instance = new CDynamicHelpDialog;
|
|
m_instance->Create( CDynamicHelpDialog::IDD,AfxGetMainWnd() );
|
|
}
|
|
m_instance->ShowWindow( SW_SHOW );
|
|
}
|
|
|
|
void CDynamicHelpDialog::OnIdle()
|
|
{
|
|
if (m_instance)
|
|
{
|
|
m_instance->OnKickIdle( 0,0 );
|
|
}
|
|
}
|
|
|
|
IMPLEMENT_DYNAMIC(CDynamicHelpDialog, CXTCBarDialog)
|
|
|
|
|
|
CDynamicHelpDialog::CDynamicHelpDialog(CWnd* pParent /*=NULL*/)
|
|
: CXTCBarDialog(CDynamicHelpDialog::IDD, pParent,SZ_NOSIZEICON )
|
|
{
|
|
xtAfxData.bControlBarMenus = TRUE; // Turned off in constructor of CXTCBarDialog.
|
|
|
|
m_bDynamicHelp = false;
|
|
m_lastWindow = NULL;
|
|
m_bEditMode = false;
|
|
m_bHelpNotFound = false;
|
|
m_bSkipSameWindow = true;
|
|
}
|
|
|
|
CDynamicHelpDialog::~CDynamicHelpDialog()
|
|
{
|
|
m_instance = 0;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CDynamicHelpDialog::PostNcDestroy()
|
|
{
|
|
CXTCBarDialog::PostNcDestroy();
|
|
delete this;
|
|
m_instance = 0;
|
|
}
|
|
|
|
|
|
void CDynamicHelpDialog::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
DDX_Control(pDX, IDC_HTMLVIEW, m_text);
|
|
CXTCBarDialog::DoDataExchange(pDX);
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CDynamicHelpDialog, CXTCBarDialog)
|
|
//ON_BN_CLICKED(IDC_SAVE, OnBnClickedSave)
|
|
//ON_BN_CLICKED(IDC_CHECK1, OnBnClickedHelp)
|
|
ON_EN_CHANGE( IDC_HTMLVIEW,OnTextChange )
|
|
ON_COMMAND( ID_HELP_SAVE,OnBnClickedSave )
|
|
ON_UPDATE_COMMAND_UI( ID_HELP_SAVE,OnUpdateSave )
|
|
ON_COMMAND( ID_HELP_GET,OnBnClickedHelp )
|
|
ON_UPDATE_COMMAND_UI( ID_HELP_GET,OnUpdateHelp )
|
|
ON_WM_MOUSEMOVE()
|
|
ON_WM_LBUTTONDOWN()
|
|
ON_WM_DESTROY()
|
|
ON_WM_SIZE()
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
// CDynamicHelpDialog message handlers
|
|
|
|
BOOL CDynamicHelpDialog::OnInitDialog()
|
|
{
|
|
CXTCBarDialog::OnInitDialog();
|
|
|
|
gDynamicHelpDialog = this;
|
|
|
|
UINT indicators[] = {
|
|
ID_SEPARATOR, // status line indicator
|
|
};
|
|
m_status.Create( this );
|
|
m_status.SetIndicators( indicators,sizeof(indicators)/sizeof(UINT) );
|
|
|
|
m_text.SetBkColor( RGB(255,255,220) ); // yellow.
|
|
|
|
m_toolbar.CreateEx( this,TBSTYLE_TRANSPARENT|TBSTYLE_FLAT|TBSTYLE_LIST,WS_CHILD|WS_VISIBLE|CBRS_TOP|CBRS_TOOLTIPS|CBRS_FLYBY );
|
|
m_toolbar.LoadToolBar( IDR_DYNAMIC_HELP );
|
|
|
|
// Set mouse hook.
|
|
hMouseHook = SetWindowsHookEx( WH_MOUSE,DynamicHelpMouseProc,AfxGetInstanceHandle(),GetCurrentThreadId() );
|
|
m_bDynamicHelp = true;
|
|
|
|
SetResize( IDC_HTMLVIEW,SZ_RESIZE(1) );
|
|
|
|
AutoLoadPlacement( "Dialogs\\DynamicHelp" );
|
|
RecalcBarLayout();
|
|
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CDynamicHelpDialog::OpenHelpFile( const CString &fname,const CString &tooltipText )
|
|
{
|
|
m_currentUrl = fname;
|
|
|
|
CString baseDir = Path::AddBackslash(GetIEditor()->GetMasterCDFolder());
|
|
|
|
CString filename = baseDir + HELP_FOLDER + "\\" + fname;
|
|
m_currentFile = filename;
|
|
|
|
m_status.SetPaneText(0,m_currentUrl);
|
|
m_bHelpNotFound = false;
|
|
|
|
//HRESULT hres;
|
|
//if (!m_bEditMode)
|
|
{
|
|
// Design mode.
|
|
CFile file;
|
|
if (file.Open( filename,CFile::modeRead ))
|
|
{
|
|
char *str = new char[file.GetLength()+1];
|
|
file.Read( str,file.GetLength() );
|
|
str[file.GetLength()] = 0;
|
|
m_text.SetWindowText( str );
|
|
delete []str;
|
|
}
|
|
else
|
|
{
|
|
CString text;
|
|
if (tooltipText.IsEmpty())
|
|
{
|
|
text = "Help not found.";
|
|
text += "\r\nPress Ctrl+Alt+Shift+LMB to edit help for this item";
|
|
}
|
|
else
|
|
{
|
|
text = tooltipText;
|
|
}
|
|
m_text.SetWindowText( text );
|
|
}
|
|
}
|
|
m_text.SetReadOnly(TRUE);
|
|
m_text.SetModify(FALSE);
|
|
m_toolbar.SetFocus();
|
|
|
|
/*
|
|
else
|
|
{
|
|
//m_pHtmlEdit->SetDesignMode(TRUE);
|
|
//m_pHtmlEdit->SetDisableEditFocusUI(true);
|
|
//m_pHtmlEdit->SetDesignMode(FALSE);
|
|
// Design mode.
|
|
CFile file;
|
|
if (file.Open( filename,CFile::modeRead ))
|
|
{
|
|
char *str = new char[file.GetLength()+1];
|
|
file.Read( str,file.GetLength() );
|
|
str[file.GetLength()] = 0;
|
|
hres = m_pHtmlEdit->NewDocument();
|
|
hres = m_pHtmlEdit->SetDocumentHTML( str );
|
|
delete []str;
|
|
}
|
|
else
|
|
{
|
|
NavigateBrowser( notFoundFilename );
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CDynamicHelpDialog::OnUpdateSave( CCmdUI* pCmdUI )
|
|
{
|
|
if (m_bEditMode && m_text.GetModify())
|
|
pCmdUI->Enable( TRUE );
|
|
else
|
|
pCmdUI->Enable( FALSE );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CDynamicHelpDialog::OnUpdateHelp( CCmdUI* pCmdUI )
|
|
{
|
|
if (m_bEditMode)
|
|
pCmdUI->Enable( TRUE );
|
|
else
|
|
pCmdUI->Enable( FALSE );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CDynamicHelpDialog::OnTextChange()
|
|
{
|
|
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CDynamicHelpDialog::OnBnClickedSave()
|
|
{
|
|
if (!m_text.GetModify())
|
|
return;
|
|
|
|
CFile file;
|
|
if (!m_currentFile.IsEmpty())
|
|
{
|
|
CString text;
|
|
m_text.GetWindowText(text);
|
|
if (file.Open( m_currentFile,CFile::modeWrite|CFile::modeCreate ))
|
|
{
|
|
file.Write( (const char*)text,text.GetLength() );
|
|
}
|
|
}
|
|
/*
|
|
// Save url file.
|
|
IHTMLDocument2* pHtmlDoc = NULL;
|
|
if (m_pHtmlEdit->GetDHtmlDocument( &pHtmlDoc ) == TRUE)
|
|
{
|
|
|
|
CComBSTR bstrHtml;
|
|
pHtmlDoc->toString( &bstrHtml );
|
|
CW2CT szMyString( bstrHtml );
|
|
}
|
|
*/
|
|
|
|
SetEditMode(false);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CDynamicHelpDialog::OnBnClickedHelp()
|
|
{
|
|
//SetCapture();
|
|
//m_pHtmlEdit->SetDesignMode(FALSE);
|
|
//m_helpBtn.SetCheck( 1 );
|
|
|
|
SetEditMode( false );
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CDynamicHelpDialog::OnDestroy()
|
|
{
|
|
UnhookWindowsHookEx( hMouseHook );
|
|
gDynamicHelpDialog = 0;
|
|
|
|
m_lastWindow = NULL;
|
|
if (GetCapture() == this)
|
|
ReleaseCapture();
|
|
CXTCBarDialog::OnDestroy();
|
|
}
|
|
|
|
void CDynamicHelpDialog::SetEditMode( bool bEditMode )
|
|
{
|
|
if (m_bEditMode == bEditMode)
|
|
return;
|
|
|
|
m_bEditMode = bEditMode;
|
|
if (m_bEditMode)
|
|
{
|
|
m_bDynamicHelp = false;
|
|
SetWindowText( "Dynamic Help (Editing)" );
|
|
m_text.SetReadOnly(FALSE);
|
|
}
|
|
else
|
|
{
|
|
OpenHelpFile( m_currentUrl,"" );
|
|
m_bDynamicHelp = true;
|
|
SetWindowText( "Dynamic Help" );
|
|
}
|
|
m_text.SetModify(FALSE);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CDynamicHelpDialog::EditItem()
|
|
{
|
|
// Edit item.
|
|
SetEditMode(true);
|
|
|
|
if (m_bHelpNotFound)
|
|
{
|
|
}
|
|
m_bHelpNotFound = false;
|
|
|
|
//m_pHtmlEdit->SetDesignMode(FALSE);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
CString CDynamicHelpDialog::GetParentText( CWnd *pWnd,const CString &text )
|
|
{
|
|
CWnd *pMain = AfxGetMainWnd();
|
|
|
|
CString temp;
|
|
CString helpId = text;
|
|
|
|
CWnd *pParent = pWnd->GetParent();
|
|
std::set<CString> duplicates;
|
|
while (pParent && pParent != pMain)
|
|
{
|
|
//id = pParent->GetDlgCtrlID();
|
|
//temp.Format("%d",id);
|
|
pParent->GetWindowText(temp);
|
|
if (!temp.IsEmpty())
|
|
{
|
|
if (duplicates.find(temp) == duplicates.end())
|
|
{
|
|
helpId = temp + CString("-") + helpId;
|
|
duplicates.insert(temp);
|
|
}
|
|
}
|
|
pParent = pParent->GetParent();
|
|
}
|
|
return helpId;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CDynamicHelpDialog::DisplayDynamicHelp()
|
|
{
|
|
if (!m_bDynamicHelp || m_bEditMode)
|
|
return;
|
|
|
|
CString helpId;
|
|
CString temp;
|
|
char className[1024];
|
|
|
|
CPoint p;
|
|
GetCursorPos(&p);
|
|
|
|
CRect selfRect;
|
|
GetWindowRect( selfRect );
|
|
if (selfRect.PtInRect(p))
|
|
{
|
|
// Point is inside Help dialog itself.
|
|
return;
|
|
}
|
|
|
|
CWnd *pWnd = WindowFromPoint(p);
|
|
|
|
// Same window as before.
|
|
if (m_lastWindow == pWnd && m_bSkipSameWindow)
|
|
return;
|
|
m_lastWindow = pWnd;
|
|
m_bSkipSameWindow = true;
|
|
|
|
CWnd *pMain = AfxGetMainWnd();
|
|
if (!pWnd || pWnd == pMain)
|
|
return;
|
|
|
|
// See if parent will be mainframe eventually.
|
|
CMainFrame *pMainFrame = (CMainFrame*)AfxGetMainWnd();
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Check if target window is child of main frame.
|
|
bool bChildWindow = false;
|
|
CWnd *pParent = pWnd->GetParent();
|
|
while (pParent)
|
|
{
|
|
if (pParent == pMain)
|
|
{
|
|
bChildWindow = true;
|
|
break;
|
|
}
|
|
pParent = pParent->GetParent();
|
|
}
|
|
if (!bChildWindow && !pMainFrame->IsDockedWindowChild(pWnd))
|
|
return;
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
bool bHelpIdFound = false;
|
|
|
|
CString tooltipText;
|
|
|
|
// Check if target window is toolbar.
|
|
GetClassName( pWnd->GetSafeHwnd(),className,sizeof(className) );
|
|
//CLogFile::FormatLine( "Class Name: %s",(const char*)className );
|
|
if (strcmp(className,TOOLBARCLASSNAME) == 0)
|
|
{
|
|
m_bSkipSameWindow = false;
|
|
CPoint tp = p;
|
|
::ScreenToClient( pWnd->GetSafeHwnd(),&tp );
|
|
int id = (int)::SendMessage(pWnd->GetSafeHwnd(),TB_HITTEST,0,(LPARAM)&tp );
|
|
if (id >= 0)
|
|
{
|
|
TBBUTTONINFO btn;
|
|
ZeroStruct(btn);
|
|
btn.cbSize = sizeof(btn);
|
|
btn.dwMask = TBIF_COMMAND|TBIF_BYINDEX;
|
|
int res = ::SendMessage( pWnd->GetSafeHwnd(),TB_GETBUTTONINFO,id,(LPARAM)&btn );
|
|
temp.Format("Command-%d",btn.idCommand);
|
|
helpId += temp;
|
|
|
|
CString szFullText;
|
|
CString strTipText;
|
|
|
|
// don't handle the message if no string resource found
|
|
if (szFullText.LoadString((UINT)btn.idCommand) != 0)
|
|
{
|
|
// this is the command id, not the button index
|
|
AfxExtractSubString(strTipText, szFullText, 1, '\n');
|
|
tooltipText = strTipText;
|
|
}
|
|
|
|
helpId = GetParentText( pWnd,helpId );
|
|
bHelpIdFound = true;
|
|
}
|
|
}
|
|
|
|
if (strcmp(className,WC_TABCONTROL) == 0)
|
|
{
|
|
m_bSkipSameWindow = false;
|
|
CPoint tp = p;
|
|
::ScreenToClient( pWnd->GetSafeHwnd(),&tp );
|
|
TCHITTESTINFO hitinfo;
|
|
hitinfo.pt = tp;
|
|
hitinfo.flags = 0;
|
|
int id = (int)::SendMessage(pWnd->GetSafeHwnd(),TCM_HITTEST,0,(LPARAM)&hitinfo );
|
|
if (id >= 0)
|
|
{
|
|
temp.Format("Tab-%d",id);
|
|
helpId += temp;
|
|
if (GetParentText( pWnd,helpId ) != helpId)
|
|
{
|
|
helpId = GetParentText( pWnd,helpId );
|
|
bHelpIdFound = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!bHelpIdFound)
|
|
{
|
|
|
|
int id = pWnd->GetDlgCtrlID();
|
|
if (id >= 0x8000)
|
|
{
|
|
temp.Format("Command-%d",id);
|
|
helpId = temp;
|
|
}
|
|
else
|
|
{
|
|
temp.Format("%d",id);
|
|
helpId = temp;
|
|
helpId = GetParentText( pWnd,temp );
|
|
}
|
|
}
|
|
|
|
CString url = helpId + ".txt";
|
|
|
|
if (url != m_currentUrl)
|
|
{
|
|
//CLogFile::FormatLine( "HelpId: %s",(const char*)helpId );
|
|
|
|
CWnd *pForeground = GetForegroundWindow();
|
|
CWnd *pWndActive = GetActiveWindow();
|
|
OpenHelpFile( url,tooltipText );
|
|
if (pWndActive)
|
|
pWndActive->SetActiveWindow();
|
|
if (pForeground)
|
|
pForeground->SetForegroundWindow();
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CDynamicHelpDialog::OnCancel()
|
|
{
|
|
DestroyWindow();
|
|
} |