AxibugEmuOnline/References/VirtuaNESex_src_191105/CHyperLink.h

251 lines
5.9 KiB
C
Raw Normal View History

2024-08-05 17:58:53 +08:00
#ifndef __CHYPERLINK_INCLUDED__
#define __CHYPERLINK_INCLUDED__
//
// <20>X<EFBFBD>^<5E>e<EFBFBD>B<EFBFBD>b<EFBFBD>N<EFBFBD>R<EFBFBD><52><EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD><EFBFBD>Subclass<73><73><EFBFBD><EFBFBD><EFBFBD>ăn<C483>C<EFBFBD>p<EFBFBD>[<5B><><EFBFBD><EFBFBD><EFBFBD>N<EFBFBD><4E><EFBFBD>T<EFBFBD>|<7C>[<5B>g
//
// Usage: CHyperLink hyperlink;
// hyperlink.Attach( GetDlgItem( hWnd, IDC_URL ) );
//
class CHyperLink
{
public:
CHyperLink() : m_hWnd(NULL), m_lpLabel(NULL),
m_hCursor(NULL), m_hFont(NULL),
m_lpHyperLink(NULL), m_lpfnOldWndProc(NULL)
{
}
~CHyperLink()
{
Detach();
}
// <20>R<EFBFBD><52><EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>ɃA<C983>^<5E>b<EFBFBD>`<60><><EFBFBD><EFBFBD>
BOOL Attach( HWND hWnd, LPCSTR lpLabel = NULL, LPCSTR lpHyperLink = NULL )
{
if( m_hWnd )
return FALSE; // <20><><EFBFBD><EFBFBD>Attach<63>ς<EFBFBD>
m_hWnd = hWnd;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>R<EFBFBD>s<EFBFBD>[
if( lpLabel ) {
m_lpLabel = new CHAR[::lstrlen(lpLabel)+1];
::lstrcpy( m_lpLabel, lpLabel );
::SendMessage( m_hWnd, WM_SETTEXT, 0, (LPARAM)m_lpLabel );
}
// <20>\<5C><><EFBFBD>ƃn<C683>C<EFBFBD>p<EFBFBD>[<5B><><EFBFBD><EFBFBD><EFBFBD>N<EFBFBD><4E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̓n<CD83>C<EFBFBD>p<EFBFBD>[<5B><><EFBFBD><EFBFBD><EFBFBD>N<EFBFBD>̓<EFBFBD><CD83>x<EFBFBD><78><EFBFBD>Ɠ<EFBFBD><C693><EFBFBD><EFBFBD><EFBFBD>
if( lpLabel && !lpHyperLink ) {
m_lpHyperLink = new CHAR[::lstrlen(lpLabel)+1];
::lstrcpy( m_lpHyperLink, lpLabel );
}
// <20>n<EFBFBD>C<EFBFBD>p<EFBFBD>[<5B><><EFBFBD><EFBFBD><EFBFBD>N<EFBFBD><4E><EFBFBD>ʂ̏ꍇ
if( lpHyperLink ) {
m_lpHyperLink = new CHAR[::lstrlen(lpHyperLink)+1];
::lstrcpy( m_lpHyperLink, lpHyperLink );
}
// <20>|<7C>C<EFBFBD><43><EFBFBD>g<EFBFBD>J<EFBFBD>[<5B>\<5C><>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>΃f<CE83>t<EFBFBD>H<EFBFBD><48><EFBFBD>g)
m_hCursor = ::LoadCursor( NULL, MAKEINTRESOURCE(32649) );
// <20>A<EFBFBD><41><EFBFBD>_<EFBFBD>[<5B><><EFBFBD>C<EFBFBD><43><EFBFBD>t<EFBFBD>H<EFBFBD><48><EFBFBD>g<EFBFBD>̍쐬
HFONT m_hOldFont = (HFONT)::SendMessage( hWnd, WM_GETFONT, 0, 0 );
LOGFONT lFont;
::GetObject( m_hOldFont, sizeof(LOGFONT), &lFont );
lFont.lfUnderline = TRUE;
m_hFont = ::CreateFontIndirect( &lFont );
// <20><><EFBFBD>x<EFBFBD><78><EFBFBD>̕\<5C><><EFBFBD>̈<EFBFBD><CC88><EFBFBD><EFBFBD>v<EFBFBD>Z
CalcLabelRectangle();
// <20>X<EFBFBD>^<5E>C<EFBFBD><43><EFBFBD>̕ύX(<28>ʒm<CA92><6D><EFBFBD>C<EFBFBD>l<EFBFBD>[<5B>u<EFBFBD><75><EFBFBD>ɂ<EFBFBD><C982><EFBFBD>)
DWORD dwStyle = ::GetWindowLong( hWnd, GWL_STYLE );
dwStyle |= SS_NOTIFY;
::SetWindowLong( hWnd, GWL_STYLE, (LONG)dwStyle );
// <20>R<EFBFBD><52><EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>̃T<CC83>u<EFBFBD>N<EFBFBD><4E><EFBFBD>X<EFBFBD><58>
m_lpfnOldWndProc = (WNDPROC)::SetWindowLong( hWnd, GWL_WNDPROC, (LONG)HyperLinkProc );
// This<69>𖄂ߍ<F0968482><DF8D><EFBFBD>
::SetWindowLong( hWnd, GWL_USERDATA, (LONG)this );
return TRUE;
}
BOOL Detach()
{
if( m_hWnd ) {
// <20>T<EFBFBD>u<EFBFBD>N<EFBFBD><4E><EFBFBD>X<EFBFBD><58><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if( m_lpfnOldWndProc ) {
::SetWindowLong( m_hWnd, GWL_WNDPROC, (LONG)m_lpfnOldWndProc );
m_lpfnOldWndProc = NULL;
}
// <20>t<EFBFBD>H<EFBFBD><48><EFBFBD>g<EFBFBD><67><EFBFBD>
if( m_hFont ) {
::DeleteObject( (HGDIOBJ)m_hFont );
m_hFont = NULL;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if( m_lpLabel ) {
delete[] m_lpLabel;
m_lpLabel = NULL;
}
if( m_lpHyperLink ) {
delete[] m_lpHyperLink;
m_lpHyperLink = NULL;
}
}
m_hWnd = NULL;
return TRUE;
}
BOOL SetLabel( LPCSTR lpLabel )
{
if( m_lpLabel ) {
delete[] m_lpLabel;
}
m_lpLabel = new CHAR[::lstrlen(lpLabel)+1];
::lstrcpy( m_lpLabel, lpLabel );
// <20>R<EFBFBD><52><EFBFBD>g<EFBFBD><67><EFBFBD>[<5B><><EFBFBD>ɕ<EFBFBD><C995><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݒ<EFBFBD>
::SendMessage( m_hWnd, WM_SETTEXT, 0, (LPARAM)m_lpLabel );
// <20><><EFBFBD>x<EFBFBD><78><EFBFBD>̕\<5C><><EFBFBD>̈<EFBFBD><CC88><EFBFBD><EFBFBD>v<EFBFBD>Z
CalcLabelRectangle();
}
BOOL SetHyperLink( LPCSTR lpHyperLink )
{
if( m_lpHyperLink ) {
delete[] m_lpHyperLink;
}
m_lpHyperLink = new CHAR[::lstrlen(lpHyperLink)+1];
::lstrcpy( m_lpHyperLink, lpHyperLink );
}
protected:
BOOL CalcLabelRectangle()
{
if( !::IsWindow(m_hWnd) )
return FALSE;
if( !m_lpLabel )
return FALSE;
RECT rcClient;
::GetClientRect( m_hWnd, &rcClient );
m_rcLabel = rcClient;
HDC hDC = ::GetDC( m_hWnd );
HFONT hOldFont = (HFONT)::SelectObject( hDC, m_hFont );
// <20>X<EFBFBD>^<5E>C<EFBFBD><43>
DWORD dwStyle = ::GetWindowLong( m_hWnd, GWL_STYLE );
INT nDrawStyle = DT_LEFT;
if( dwStyle && SS_CENTER ) {
nDrawStyle = DT_CENTER;
} else if( dwStyle && SS_RIGHT ) {
nDrawStyle = DT_RIGHT;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\<5C><><EFBFBD>ƕ`<60><><EFBFBD>̈<EFBFBD><CC88>̌v<CC8C>Z
::DrawText( hDC, m_lpLabel, -1, &m_rcLabel, nDrawStyle | DT_WORDBREAK | DT_CALCRECT );
::SelectObject( hDC, hOldFont );
// <20>X<EFBFBD>^<5E>C<EFBFBD><43><EFBFBD>ɂ<EFBFBD><C982><EFBFBD><EFBFBD>ăI<C483>t<EFBFBD>Z<EFBFBD>b<EFBFBD>g<EFBFBD><67><EFBFBD>v<EFBFBD>Z
if( dwStyle & SS_CENTER ) {
::OffsetRect( &m_rcLabel, (rcClient.right - m_rcLabel.right) / 2, 0 );
} else if (dwStyle & SS_RIGHT) {
::OffsetRect( &m_rcLabel, rcClient.right - m_rcLabel.right, 0 );
}
return true;
}
static LRESULT CALLBACK HyperLinkProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
CHyperLink* pHyperLink = reinterpret_cast<CHyperLink*>(::GetWindowLong( hWnd, GWL_USERDATA));
switch( msg ) {
case WM_DESTROY:
{
// 2003/10/11 <20><><EFBFBD><EFBFBD><EFBFBD>[<5B>X<EFBFBD><58><EFBFBD><EFBFBD>fix...
WNDPROC pWndProcOld = pHyperLink->m_lpfnOldWndProc;
pHyperLink->Detach();
return CallWindowProc( pWndProcOld, hWnd, msg, wParam, lParam );
}
break;
case WM_LBUTTONDOWN: {
POINT pt = { LOWORD(lParam), HIWORD(lParam) };
if( pHyperLink->m_lpLabel && pHyperLink->m_lpHyperLink ) {
if( ::PtInRect( &pHyperLink->m_rcLabel, pt ) ) {
::ShellExecute( hWnd, NULL, pHyperLink->m_lpHyperLink, NULL, NULL, SW_SHOWNORMAL );
return TRUE;
}
}
}
break;
case WM_MOUSEMOVE: {
POINT pt = { LOWORD(lParam), HIWORD(lParam) };
if( pHyperLink->m_lpLabel && pHyperLink->m_lpHyperLink ) {
if( ::PtInRect( &pHyperLink->m_rcLabel, pt ) ) {
::SetCursor( pHyperLink->m_hCursor );
return TRUE;
}
}
}
break;
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hDC = ::BeginPaint( hWnd, &ps );
DWORD dwStyle = ::GetWindowLong( hWnd, GWL_STYLE );
INT nDrawStyle = DT_LEFT;
if( dwStyle && SS_CENTER ) {
nDrawStyle = DT_CENTER;
} else if( dwStyle && SS_RIGHT ) {
nDrawStyle = DT_RIGHT;
}
// <20>A<EFBFBD>g<EFBFBD><67><EFBFBD>r<EFBFBD><72><EFBFBD>[<5B>g
::SetBkMode( hDC, TRANSPARENT );
::SetTextColor( hDC, 0x00FF0000 );
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\<5C><>
if( pHyperLink->m_lpLabel ) {
HFONT hOldFont = (HFONT)::SelectObject( hDC, pHyperLink->m_hFont );
::DrawText( hDC, pHyperLink->m_lpLabel, -1, &pHyperLink->m_rcLabel, nDrawStyle | DT_WORDBREAK );
::SelectObject( hDC, hOldFont );
}
::EndPaint( hWnd, &ps );
}
return TRUE;
default:
break;
}
return CallWindowProc( pHyperLink->m_lpfnOldWndProc, hWnd, msg, wParam, lParam );
}
HWND m_hWnd;
HFONT m_hFont;
HFONT m_hOldFont;
HCURSOR m_hCursor;
WNDPROC m_lpfnOldWndProc;
RECT m_rcLabel;
LPSTR m_lpLabel;
LPSTR m_lpHyperLink;
private:
};
#endif // !__CHYPERLINK_INCLUDED__