例外処理まとめ

 以下はダイアログの初期化での覚書。

BOOL CMyApp::OnInitDialog() {
	/* 前略 */

	try {
		throw "例外メッセージを好きに指定。catch (char *e)";
		// AfxThrowUserException(); // 既定のユーザ例外?メッセージの指定方法がわからん
	} catch (char *e) {
		this->MessageBox(e, "初期化エラーが発生しました", MB_ICONERROR);
	} catch (CException *e) {
		char errmsg[255];
		e->GetErrorMessage(errmsg, 255);
		this->MessageBox(errmsg, "初期化エラーが発生しました", MB_ICONERROR);
		e->Delete();
	}

	/* 後略 */
}

ダイアログを画面いっぱいに表示する - フルスクリーン表示?

/*
 * CDialog をフルスクリーン表示
 * @param HWND *hWnd
 * @return bool
 */
const bool fullscreen(CDialog *dlg) {
	try {
		RECT rc;
		dlg->GetWindowRect(&rc);
		int width = GetSystemMetrics(SM_CXSCREEN);
		int height = GetSystemMetrics(SM_CYSCREEN);
		dlg->MoveWindow(0, 0, width, height, TRUE);
		return true;
	} catch (char *e) {
		OutputDebugString(e); OutputDebugString("\n");
	} catch (CException *e) {
		TCHAR errmsg[255];
		e->GetErrorMessage(errmsg, 255);
		OutputDebugString(errmsg); OutputDebugString("\n");
		e->Delete();
	}
	return false;
}

int GetSystemMetrics( int nIndex )

さまざまなシステムメトリックの値(表示要素の幅と高さ)とシステムの現在の構成を取得します。表示要素とは、ウィンドウの一部、またはシステムが表示する画面の一部を意味します(詳細については、GetSysColor 関数の説明を参照してください)。GetSystemMetrics 関数は、すべてのサイズをピクセル単位で取得します。

Windows7 でタスクバーを隠す

 フルスクリーン描画したいのに、タスクバーが前面に出ちゃってどうしようもないときにした対応の覚書。

概要

 タスクバーウィンドウを獲得して、表示を隠す指示を出す。
 そのままにすると、アプリを終了しても隠れたままになってしまうので、終了時に元に戻すようにする。

問題点

 この方法では、フルスクリーン状態で別のウィンドウをアクティブにしても、タスクバーは戻らない。
 対応するとしたらイベントハンドラとかか。

サンプル

 以下はダイアログアプリのサンプル。

/*
 * タスクバー獲得と非表示処理
 */
HWND taskbar = ::FindWindow("Shell_TrayWnd" , NULL);
// タスクバースタートボタン
HWND taskbar_button = NULL;
if (taskbar != NULL) {
	// タスクバースタートボタン獲得 from タスクバー
	taskbar_button = ::FindWindowEx(taskbar, NULL, "Button", NULL);
	if (taskbar_button == NULL) {
		// タスクバーからスタートボタンを獲得できない場合
		// 全体から獲得
		taskbar_button = ::FindWindow("Button" , NULL);
	}
	// タスクバーを隠す
	::ShowWindow(taskbar, SW_HIDE);
	if (taskbar_button != NULL) {
		// タスクバーボタンを隠す
		::ShowWindow(taskbar_button, SW_HIDE);
	}
}
/* // タスクバー獲得と非表示処理 */

try {
	MyAppDlg dlg;
	m_pMainWnd = &dlg;
	INT_PTR nResponse = dlg.DoModal();
	if (nResponse == IDOK)
	{
		// TODO: ダイアログが <OK> で消された時のコードを
		//  記述してください。
	}
	else if (nResponse == IDCANCEL)
	{
		// TODO: ダイアログが <キャンセル> で消された時のコードを
		//  記述してください。
	}
} catch (char *e) {
	AfxMessageBox(e, MB_ICONWARNING);
} catch (CException *e) {
	e->ReportError();
	e->Delete();
}

/*
 * タスクバー復帰
 */
if (taskbar != 0) {
	// タスクバーを隠す
	::ShowWindow(taskbar, SW_SHOWDEFAULT);
	if (taskbar_button != NULL) {
		// タスクバーボタンを隠す
		::ShowWindow(taskbar_button, SW_SHOWDEFAULT);
		::DestroyWindow(taskbar_button); // 解放
	}
	::DestroyWindow(taskbar); // 解放
}
/* // タスクバー復帰 */

みんな大好き、シングルトン

ヘッダ

#pragma once

class MyUser
{
private:
	static MyUser* user;
	MyUser(void); // コンストラクタ隠蔽

public:
	~MyUser(void); // デストラクタ

	static MyUser* getInstance();
};

実装

#pragma once
#include "StdAfx.h"

MyUser* MyUser::user = NULL; // シングルトン初期化

MyUser::MyUser()
{
	// コンストラクタ
}

MyUser::~MyUser(void)
{
	// デストラクタ
}

MyUser *MyUser::getInstance() {
	OutputDebugString("MyUser::getInstance()\r\n");
	if ( user == NULL ) {
		OutputDebugString("MyUser::getInstance() create instance\r\n");
		user = new MyUser();
	}
	return user;
}

利用

MyUser *user = MyUser::getInstance();

SWF に日本語混じりのBase URL を渡せない

 SWF ブラウザ的なアプリで SWF 動作にBase URL の指定が必要なんだが、フォルダ名に日本語などのマルチバイト文字が混ざっていると渡した後に文字化けしてしまう。

 文字セットをマルチバイトにしてもUnicode にしても同じ症状、同じ文字化け。

CString baseurl = "file:///c:/フォルダ名/";
this->swf.put_Base( baseurl );

 put_Base は (ActiveX Control) ShockwaveFlash を追加すると作成されるshockwaveflash1 クラスで定義されるメソッドで、中身はただのInvokeHelper。

	void put_Base(LPCTSTR newValue)
	{
		static BYTE parms[] = VTS_BSTR ;
		InvokeHelper(0x88, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
	}

 厄介なのは、呼び出すSWF のURL にマルチバイト文字が混ざっていても問題なく起動できる点。

	void put_Movie(LPCTSTR newValue)
	{
		static BYTE parms[] = VTS_BSTR ;
		InvokeHelper(0x66, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue);
	}

 base の指定も movie の指定も、同じように InvokeHelper 。movie 指定の動作を見る限り、AcitveX コントロールがうまいこと文字コードを調整してくれているようで、External Interface を介したSWF とのデータのやり取りでも特に問題がない。

 問題を引き起こすのは Base URL の指定だけ。

 マルチバイトの部分をURL エンコードしてみても、むしろパスを解釈しない。UTF8 でも Shift_JIS でも同様。

 情報が足りない。調べても分からない。そもそも (ActiveX Control) ShockwaveFlash の情報が少なすぎる。

 Base URL の指定なしで動作するようにフォルダ構成を調整できればいいんだが、それだとクライアントの要件と噛み合わない。

 さて、どうしたものか。