|
前作の Color Maker から正式な(?)デザイナーが加わった事により、いままで苦労してきたアイコンの作成やアバウト画面に華が付いた。
旧禿ソフトウェアからの読者(会員)の方はご存知かと思うが、私のつくるアイコンやロゴマークと言ったらそれはもう・・・何をあらわしているのかさっぱり... デザイナーが加わった事により人様の前に大きくアバウトダイアログを出す事ができるようになった。 |
|
|
|
ここまで読んで、アバウトダイアログ?となっている方の為に下に画面キャプチャを載せておく
この画面を「バージョン情報のダイアログ」と呼んでいる方がほとんどだと思う。 しかし、私は「アバウトダイアログ」なのである。 「なぜか?」と聞かれても「さぁ?」ぐらいの気持ちなので突っ込まないでください (^^; |
|
|
|
この画面の左下に「antenn-a」とカラフルに書かれた部分にカーソルを持っていくと指カーソルになり、押すとブラウザが立ち上がる。 そして[http://www.antenn-a.com」に繋げるよくある設定である。 その他に右下にある人名「antenn-a, Yuta, SEK, HAGERU」の部分にカーソルを持っていくとやはり指カーソルになり、押すとデフォルトで指定したメーラーが立ち上がるようになっている。 読者の方がこのようなダイアログを作成しようと思った場合どのようにして実装を試みるだろうか? |
|
|
|
私は極めてシンプルに実装を試みた。(何にも考えていないとも言う) このダイアログのリソースを下に載せておく。
ここに見えるスタティックテキストとボタンは可視属性を抜いている。 すなわち見えないウィンドウである。 ただ、マウスの位置を知る為の境界線だと思っていただいてかまわない。 |
|
|
|
実装方法は以下の通りである。
|
|
|
|
以上のようにソースを書いてやればいいはずである。 以下ソースコード
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
~CAboutDlg();
void DoAction();
CDC* m_pdcDisplayMemory;
CBitmap* m_pBitmap;
CSize m_sizeSource;
CSize m_sizeDest;
BOOL FingerFlag;
short ActionFlag;
CRect RctUrl;
CRect RctAntenna;
CRect RctYuta;
CRect RctSek;
CRect RctHageru;
// ダイアログ データ
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
CStatic m_StcAntenna;
CStatic m_StcYuta;
CStatic m_StcUrl;
CStatic m_StcSek;
CStatic m_StcHageru;
//}}AFX_DATA
// ClassWizard は仮想関数のオーバーライドを生成します
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX);
// DDX/DDV のサポート
//}}AFX_VIRTUAL
// インプリメンテーション
protected:
//{{AFX_MSG(CAboutDlg)
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
ON_WM_PAINT()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_SETCURSOR()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
m_pdcDisplayMemory = new CDC;
m_pBitmap = new CBitmap;
FingerFlag = FALSE;
}
CAboutDlg::~CAboutDlg()
{
delete m_pdcDisplayMemory;
delete m_pBitmap;
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
DDX_Control(pDX, IDC_STC_ANTENNA, m_StcAntenna);
DDX_Control(pDX, IDC_STC_YUTA, m_StcYuta);
DDX_Control(pDX, IDC_STC_URL, m_StcUrl);
DDX_Control(pDX, IDC_STC_SEK, m_StcSek);
DDX_Control(pDX, IDC_STC_HAGERU, m_StcHageru);
//}}AFX_DATA_MAP
}
BOOL CAboutDlg::OnInitDialog()
{
CDialog::OnInitDialog();
BITMAP bm;
if (m_pdcDisplayMemory->GetSafeHdc() == NULL) {
CClientDC dc(this);
dc.SetBkColor( RGB( 0, 0, 0 ) );
m_pBitmap->LoadBitmap( IDB_ABOUT );
m_pdcDisplayMemory->CreateCompatibleDC(&dc);
m_pdcDisplayMemory->SelectObject(m_pBitmap);
m_pBitmap->GetObject(sizeof(bm), &bm);
m_sizeSource.cx = bm.bmWidth;
m_sizeSource.cy = bm.bmHeight;
m_sizeDest = m_sizeSource;
dc.DPtoLP(&m_sizeDest);
}
//
m_StcUrl.GetWindowRect( RctUrl );
m_StcAntenna.GetWindowRect( RctAntenna );
m_StcYuta.GetWindowRect( RctYuta );
m_StcSek.GetWindowRect( RctSek );
m_StcHageru.GetWindowRect( RctHageru );
ScreenToClient( RctUrl );
ScreenToClient( RctAntenna );
ScreenToClient( RctYuta );
ScreenToClient( RctSek );
ScreenToClient( RctHageru );
//
return TRUE;
// コントロールにフォーカスを設定しないとき、戻り値は TRUE となります
// 例外: OCX プロパティ ページの戻り値は FALSE となります
}
void CAboutDlg::OnPaint()
{
CPaintDC dc(this); // 描画用のデバイス コンテキスト
dc.StretchBlt( 0, 0,
m_sizeDest.cx,
m_sizeDest.cy,
m_pdcDisplayMemory,
0, 0,
m_sizeSource.cx,
m_sizeSource.cy,
SRCCOPY
);
// 描画用メッセージとして CDialog::OnPaint() を呼び出してはいけません
}
#define AN_NONE 0
#define AN_URL 1
#define AN_ANTENNA 2
#define AN_YUTA 3
#define AN_SEK 4
#define AN_HAGERU 5
BOOL CAboutDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
CPoint point;
HCURSOR m_hCursor;
GetCursorPos( &point );
ScreenToClient( &point );
if( RctUrl.PtInRect( point ) )
ActionFlag = AN_URL;
else if( RctAntenna.PtInRect( point ) )
ActionFlag = AN_ANTENNA;
else if( RctYuta.PtInRect( point ) )
ActionFlag = AN_YUTA;
else if( RctSek.PtInRect( point ) )
ActionFlag = AN_SEK;
else if( RctHageru.PtInRect( point ) )
ActionFlag = AN_HAGERU;
else
ActionFlag = AN_NONE;
if( ActionFlag != AN_NONE ){
m_hCursor = ::LoadCursor( AfxGetInstanceHandle(),
MAKEINTRESOURCE( IDC_CUR_FINGER_OFF )
);
SetCursor( m_hCursor );
//
return TRUE;
}
return CDialog::OnSetCursor(pWnd, nHitTest, message);
}
void CAboutDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
HCURSOR m_hCursor;
if( ActionFlag != AN_NONE ){
m_hCursor = ::LoadCursor( AfxGetInstanceHandle(),
MAKEINTRESOURCE( IDC_CUR_FINGER_ON )
);
SetCursor( m_hCursor );
}
CDialog::OnLButtonDown(nFlags, point);
}
void CAboutDlg::OnLButtonUp(UINT nFlags, CPoint point)
{
HCURSOR m_hCursor;
if( ActionFlag != AN_NONE ){
m_hCursor = ::LoadCursor( AfxGetInstanceHandle(),
MAKEINTRESOURCE( IDC_CUR_FINGER_OFF )
);
SetCursor( m_hCursor );
//
DoAction();
}
CDialog::OnLButtonUp(nFlags, point);
}
void CAboutDlg::DoAction()
{
switch( ActionFlag ){
case AN_URL:
::ShellExecute( *this,
"open",
"http://www.antenn-a.com",
NULL,
NULL,
SW_SHOWNORMAL
);
break;
case AN_ANTENNA:
::ShellExecute( *this,
"open",
"mailto:contact-us@antenn-a.com",
NULL,
NULL,
SW_SHOWNORMAL
);
break;
case AN_YUTA:
::ShellExecute( *this,
"open",
"mailto:contact-us@antenn-a.com",
NULL,
NULL,
SW_SHOWNORMAL
);
break;
case AN_SEK:
::ShellExecute( *this,
"open",
"mailto:sek@antenn-a.com",
NULL,
NULL,
SW_SHOWNORMAL
);
break;
case AN_HAGERU:
::ShellExecute( *this,
"open",
"mailto:enomoto@antenn-a.com",
NULL,
NULL,
SW_SHOWNORMAL
);
break;
}
}
|
|
|
|
今回実装を試みたプログラムはテクニック的には対した事無いが、複合技が出てるので色々な意味で勉強になると思う。 これを参考にして是非、格好よいアバウトダイアログを作ってもらいたい。 今回のサンプルはここからダウンロードできる。 |