Files
FC1/Editor/DynamicHelpDialog.cpp
romkazvo 34d6c5d489 123
2023-08-07 19:29:24 +08:00

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();
}