MFC AppWizardを使ってMDI/SDIのプロジェクトを作成すると、
デフォルトで1つのツールバーがくっついてきます。
IEのように、ボタン1つ1つにテキストを挿入しようと思い、
ツールバー作成コードのすぐ後へ次のようなコードを書きました。

m_wndToolBar.SetButtonText(0,"新規作成");
m_wndToolBar.SetButtonText(1,"開く");

ところがどっこい、実行してみると・・・

という感じでテキストが埋もれてしまいます。

ここで詰まった方も多いはず。。。

マニュアルにも特に記載されてません。

というわけで、次のが直す方法。

CRect rect;
m_wndToolBar.GetToolBarCtrl().GetItemRect(0,rect);
m_wndToolBar.SetSizes(rect.Size(),CSize(16,15));

これを、テキスト設定後に実行すると、ちゃんと表示されるようになります(CSize(16, 15)はボタン画像のサイズです)。

C/C++言語で文字列解析をやる場合に避けては通れない部分、それが半角・全角の判定です(※ マルチバイト環境に限ります)。
とは言っても、実際には文字が1バイト長か、2バイト長かを判定します。

何バイト文字かを判定する関数は「_mbclen()」です。引数に、文字列を指定してやると、
先頭の文字が1バイトなのか2バイトなのかを返してくれます。

char *str="あいabcうえお";
printf("byte=%d\n",_mbclen((BYTE *)str));

上の例の場合、画面には2が出力されます。

ついでに、一文字ずつ表示する例も記述しておきます。

char *Str="あいabcうえお";
char *p=Str;
char tmp[3];
while(*p!='\0'){
	switch(_mbclen((BYTE*)p)){
	case 1:
		tmp[0]=*(p++);
		tmp[1]='\0';
		break;
	case 2:
		tmp[0]=*(p++);
		tmp[1]=*(p++);
		tmp[2]='\0';
		break;
	default:
		//error
		break;
	}
	printf("%s\n",tmp);
}

よく、条件によって、代入する値を変更する場合があります。

if(bFlag)
	nValue=16;
else
	nValue=165;

上のプログラムを三項演算子を使って書き直すと、次のようになります。

nValue = bFlag ? 16 : 165;

すっきりしましたね(ちょっと見にくいかもしれませんが)。

三項演算子の構文は次のような感じです。

左辺 = 条件式 ? 条件式が真の場合に代入する値 : 条件式が偽の場合に代入する値 ;

代入の時で無くても、値を必要とする場合ならばどこでも使用出来ます。

printf("%d\n", bFlag ? 16 : 126);

ついでに、関数も呼べます。

bFlag ? printf("真") : printf("偽");

文字列にも使えます(数値と同じですね)。

printf("%s\n", bFlag ? "真" : "偽");

結構使い道はあると思います。

何かアクションが起こった際(例えばマウスクリック時)に、キーボードが押されているかどうかを判定したい場合があります(シフトキー等)。

そんな時には「GetKeyState関数」を使います。

押されていると、SHORT型の最上位ビットが1になります。

最下位ビットが1のときはキーがトグル状態にあることを、0のときはトグルが解除されていることを示します。

//シフトキーの判定例(& 0x80でも良いみたい)
if(GetKeyState(VK_SHIFT) & 0x8000){
	//処理
}

ちなみに、シフトやコントロールキーと言ったキーはマクロで定義されていますが(VK_SHIFT等)、
通常の「A」や「B」と言ったキーは定義されていません。これらのキーは、キーコードを指定しれやれば良いです。

if(GetKeyState('A') & 0x8000){
	//処理
}

同時に全キー状態を取得したい場合には、「GetKeyboardState関数」を使います。
この関数は、256バイトの配列を引き渡してやると、そこへ各キーの状態を詰め込んでくれます。

こちらも、最上位ビットが1の場合は押されているという事になります。

BYTE KeyState[256];
GetKeyboardState(KeyState);

//シフトキー判定例
if(KeyState[VK_SHIFT] & 0x80){
	//処理
}

MFC AppWizardを使ってプロジェクトを作成すると、’C’+プロジェクト名+’App’という感じのクラスが作成されます。
このクラスはCWinAppの派生クラスであり、アプリケーションを管理するクラスとなります。
よく、いろいろなクラスからデータを共有したい場合、グローバル変数を使用するのは嫌われるため、このCWinAppの派生クラスのメンバ変数として宣言します。
この場合、そのメンバ変数へアクセスするために、例えばそのCWinAppの派生クラスが「CMfcTestApp」という名前ならば、

CMfcTestApp *pApp=(CMfcTestApp *)AfxGetApp();
pApp->m_・・・・

とします。

一度で良いならば、

((CMfcTestApp *)AfxGetApp())->m_・・・・

でも良いですね。

ただ、こうした事を何度も書いていると、ソースも見にくくなるし、面倒くさくなってきます。
マクロを使うという手もありますが、今回は別の方法をご紹介します。

MfcTestAppのソースファイルを覗いてみると、こんな記述があります。

/////////////////////////////////////////////////////
// 唯一の CMfcTestApp オブジェクト

CMfcTestApp theApp;

という事は、こいつをどこでも使えるようにすれば、手軽にCMfcTestAppクラスへアクセス出来るわけですね。
というわけで、externを使って、CMfcTestAppのヘッダーファイルの最後の方(クラス宣言が終わった次くらい)へ次のような文字列を埋め込みます。

extern CMfcTestApp theApp;

「CMfcTestApp」というは例なので、自分の派生クラス名にしてください。

こうすれば、あとはどこでも、

theApp.m_・・・

という感じでメンバ変数へアクセス出来るようになるというわけです。

・・・。

やっぱり、こういうやり方って邪道なんでしょうかねぇ(^^;

1 4 5 6 7 8 9

記事検索

アーカイブ