AutoCAD 3DMAX C语言 Pro/E UG JAVA编程 PHP编程 Maya动画 Matlab应用 Android
Photoshop Word Excel flash VB编程 VC编程 Coreldraw SolidWorks A Designer Unity3D
 首页 > VC编程

用VC++在基于对话框的程序中动态更改光标

51自学网 2015-08-30 http://www.wanshiok.com

  三、程序代码

////////////////////////////////////////////////////////////////////////////
#ifndef _HYPRILNK_H
#define _HYPRILNK_H
// Simple text hyperlink derived from CString
class CHyperlink : public CString {
public:
 CHyperlink(LPCTSTR lpLink = NULL) : CString(lpLink) { }
 ~CHyperlink() { }
 const CHyperlink& operator=(LPCTSTR lpsz) {
  CString::operator=(lpsz);
  return *this;
 }
 operator LPCTSTR() {
  return CString::operator LPCTSTR();
 }
 virtual HINSTANCE Navigate() {
  return IsEmpty() ? NULL :
  ShellExecute(0, _T("open"), *this, 0, 0, SW_SHOWNORMAL);
 }
};
#endif
/////////////////////////////////////////////////////////////////////////////////
#ifndef _STATLINK_H
#define _STATLINK_H
#include "HyprLink.h"
class CStaticLink : public CStatic {
public:
 DECLARE_DYNAMIC(CStaticLink)
 CStaticLink(LPCTSTR lpText = NULL, BOOL bDeleteOnDestroy=FALSE);
 ~CStaticLink() { }
 // Hyperlink contains URL/filename. If NULL, I will use the window text.
 // (GetWindowText) to get the target.
 CHyperlink m_link;
 COLORREF m_color;
 // Default colors you can change
 // These are global, so they're the same for all links.
 static COLORREF g_colorUnvisited;
 static COLORREF g_colorVisited;
 static HCURSOR g_hCursorLink;
protected:
 CFont m_font; // underline font for text control
 BOOL m_bDeleteOnDestroy; // delete object when window destroyed?
 virtual void PostNcDestroy();
 // message handlers
 DECLARE_MESSAGE_MAP()
 afx_msg UINT OnNcHitTest(CPoint point);
 afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
 afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
 afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
};
#endif _STATLINK_H
/////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "StatLink.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
COLORREF CStaticLink::g_colorUnvisited = RGB(0,0,255); // blue
COLORREF CStaticLink::g_colorVisited = RGB(128,0,128); // purple
HCURSOR CStaticLink::g_hCursorLink = NULL;
IMPLEMENT_DYNAMIC(CStaticLink, CStatic)
BEGIN_MESSAGE_MAP(CStaticLink, CStatic)
ON_WM_NCHITTEST()
ON_WM_CTLCOLOR_REFLECT()
ON_WM_LBUTTONDOWN()
ON_WM_SETCURSOR()
END_MESSAGE_MAP()
///////////////////
// Constructor sets default colors = blue/purple.
// bDeleteOnDestroy is used internally by PixieLib in CPixieDlg.
CStaticLink::CStaticLink(LPCTSTR lpText, BOOL bDeleteOnDestroy)
{
 m_link = lpText; // link text (NULL ==> window text)
 m_color = g_colorUnvisited; // not visited yet
 m_bDeleteOnDestroy = bDeleteOnDestroy; // delete object with window?
}
//////////////////
// Normally, a static control does not get mouse events unless it has
// SS_NOTIFY. This achieves the same effect as SS_NOTIFY, but it's fewer
// lines of code and more reliable than turning on SS_NOTIFY in OnCtlColor
// because Windows doesn't send WM_CTLCOLOR to bitmap static controls.
//
UINT CStaticLink::OnNcHitTest(CPoint point)
{
 return HTCLIENT;
}

//////////////////
// Handle reflected WM_CTLCOLOR to set custom control color.
// For a text control, use visited/unvisited colors and underline font.
// For non-text controls, do nothing. Also ensures SS_NOTIFY is on.
//
HBRUSH CStaticLink::CtlColor(CDC* pDC, UINT nCtlColor)
{
 ASSERT(nCtlColor == CTLCOLOR_STATIC);
 DWORD dwStyle = GetStyle();

 HBRUSH hbr = NULL;
 if ((dwStyle & 0xFF) <= SS_RIGHT) {

  // this is a text control: set up font and colors
  if (!(HFONT)m_font) {
   // first time init: create font
   LOGFONT lf;
   GetFont()->GetObject(sizeof(lf), &lf);
   lf.lfUnderline = TRUE;
   m_font.CreateFontIndirect(&lf);
  }
  // use underline font and visited/unvisited colors
  pDC->SelectObject(&m_font);
  pDC->SetTextColor(m_color);
  pDC->SetBkMode(TRANSPARENT);
  // return hollow brush to preserve parent background color
  hbr = (HBRUSH)::GetStockObject(HOLLOW_BRUSH);
 }
 return hbr;
}
/////////////////
// Handle mouse click: navigate link
//
void CStaticLink::OnLButtonDown(UINT nFlags, CPoint point)
{
 if (m_link.IsEmpty()) {
  // no link: try to load from resource string or window text
  m_link.LoadString(GetDlgCtrlID()) || (GetWindowText(m_link),1);
  if (m_link.IsEmpty())
  return;
 }
 // Call ShellExecute to run the file.
 // For an URL, this means opening it in the browser.
 //
 HINSTANCE h = m_link.Navigate();
 if ((UINT)h > 32) { // success!
  m_color = g_colorVisited; // change color
  Invalidate(); // repaint
 } else {
  MessageBeep(0); // unable to execute file!
  TRACE(_T("*** WARNING: CStaticLink: unable to navigate link %s/n"),(LPCTSTR)m_link);
 }
}

//////////////////
// Set "hand" cursor to cue user that this is a link. If app has not set
// g_hCursorLink, then try to get the cursor from winhlp32.exe,
// resource 106, which is a pointing finger. This is a bit of a kludge,
// but it works.
//
BOOL CStaticLink::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
 if (g_hCursorLink == NULL) {
  static bTriedOnce = FALSE;
  if (!bTriedOnce) {
   CString windir;
   GetWindowsDirectory(windir.GetBuffer(MAX_PATH), MAX_PATH);
   windir.ReleaseBuffer();
   windir += _T("//winhlp32.exe");
   HMODULE hModule = LoadLibrary(windir);
   if (hModule) {
    g_hCursorLink = CopyCursor(::LoadCursor(hModule, MAKEINTRESOURCE(106)));
   }
   FreeLibrary(hModule);
   bTriedOnce = TRUE;
  }
 }
 if (g_hCursorLink) {
  ::SetCursor(g_hCursorLink);
  return TRUE;
 }
 return FALSE;
}

//////////////////
// Normally, a control class is not destoyed when the window is;
// however, CPixieDlg creates static controls with "new" instead of
// as class members, so it's convenient to allow the option of destroying
// object with window. In applications where you want the object to be
// destoyed along with the window, you can call constructor with
// bDeleteOnDestroy=TRUE.
//
void CStaticLink::PostNcDestroy()
{
 if (m_bDeleteOnDestroy)
 delete this;
}
//////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "resource.h"
#include "TraceWin.h"
#include "StatLink.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
class CMyDialog : public CDialog {
public:
 CMyDialog(CWnd* pParent = NULL);
 ~CMyDialog();
 //protected:
private:
 HICON m_hIcon;
 CStaticLink m_wndLink1; // web links
 CStaticLink m_wndLink2;
 // the button cursor
 HCURSOR m_hButtonCursor;
 virtual BOOL OnInitDialog();
 afx_msg void OnPaint();
 afx_msg HCURSOR OnQueryDragIcon();
 afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT msg);
 DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CMyDialog, CDialog)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_SETCURSOR()
END_MESSAGE_MAP()

CMyDialog::CMyDialog(CWnd* pParent /*=NULL*/)
: CDialog(IDD_MYDIALOG, pParent)
{}

CMyDialog::~CMyDialog()
{}

//////////////////
// Initialize dialog
//
BOOL CMyDialog::OnInitDialog()
{
 CDialog::OnInitDialog();
 // set up hyperlinks
 m_wndLink1.m_link = _T("http://www.vckbase.com");
 m_wndLink2.m_link = _T("mailto:vckbase@public.hk.hi.cn");
 m_wndLink1.SubclassDlgItem(IDC_PDURL, this);
 m_wndLink2.SubclassDlgItem(IDC_MSDNURL, this);
 // Set the icon for this dialog. The framework does this automatically
 // when the application's main window is not a dialog
 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
 SetIcon(m_hIcon, TRUE); // Set big icon
 SetIcon(m_hIcon, FALSE); // Set small icon
 // load button cursor
 m_hButtonCursor = AfxGetApp()->LoadCursor(IDC_MYHAND);
 return TRUE; // return TRUE unless you set the focus to a control
}

//////////////////
// Set cursor if mouse is over a button.
//
BOOL CMyDialog::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT msg)
{
 CString sClassName;
 ::GetClassName(pWnd->GetSafeHwnd(),sClassName.GetBuffer(80),80);
 if (sClassName=="Button" && m_hButtonCursor) {
  ::SetCursor(m_hButtonCursor);
  return TRUE;
 }
 return CDialog::OnSetCursor(pWnd, nHitTest, msg);
}

  四、小结

  本文不仅介绍了动态改变程序中的鼠标形状,还介绍了如何实现静态文本的超连接,读者朋友可以将这部分代码修改后应用到自己开放的应用程序中,例如在程序中添加自己的网页和邮箱地址等,我想这一定是件很令人鼓舞的事情吧。

 
 
说明
:本教程来源互联网或网友上传或出版商,仅为学习研究或媒体推广,wanshiok.com不保证资料的完整性。

上一篇:Visual&nbsp;C++&nbsp;6.0编程实现打印功能  下一篇:用VC实现多串口多线程工业控制