トップページ⇒tech
1001コメント291KB

■MFC相談室 mfc11.dll■

■ このスレッドは過去ログ倉庫に格納されています
0001デフォルトの名無しさんNGNG
Microsoft Foundation Classライブラリ専用スレです。

前スレ
■ VisualC++(MFC限定)相談室 MFC10.dll■
http://pc5.2ch.net/test/read.cgi/tech/1074104008/

関連リンクは >>2-10 の辺り。
0092デフォルトの名無しさんNGNG
>>89
そのスレッドでダイアログの情報を持ってないのが原因だろうから、
何らかの方法でCWnd*を渡してメンバ関数版を使えばいいんでないかな。
0093デフォルトの名無しさんNGNG
>>89
試していないけど、CHogeDlgがCDialogを継承
しているならのメンバ関数のメッセージボックスを
呼び出せばいいんじゃないの?
0094デフォルトの名無しさんNGNG
>>89
>ダイアログの中央に出す方法はありませんか?
方法はある。 WM_INITDIALOG
もっと簡単な方法が知りたいってことか?
どんくらいまでわかるのかを書かないと
それこそ基本中の基本から説明せにゃならん。
もちろん、それは万単位が相場で只ではできない。
0095デフォルトの名無しさんNGNG
MDIでフォームビューを選んだとき、フォームのダイアログのサイズを
MoveWindow()とかSetWindowPos()でサイズを変えようとすると
必ず落ちますが(DEBUGビルド時)、これって許されないのでしょうか。
CChildFrameのサイズに合わせて大きさを変えたいのですけど。
009695NGNG
>>95
簡単にいいますと、フォーム内のダイアログテンプレートのサイズを
変更するにはどうしたら良いのか、ということです。
単純にGetDlgItem()ではダメですよね。NULLが返ってきてしまいます。
009789NGNG
>>91,92,93,94
回答ありがとうございます。
とりあえずスレッド作成元のCWnd*をグローバル変数に設定して、
スレッド内からMessageBoxを呼び出す方法と、直接メンバ関数の
MessageBoxを呼び出す方法を試しましたが、結果は同様でした。
なお作成元のスレッドでAfxMessageBoxを呼び出した場合には、ダイアログの
中央に表示されます。
>>94
当方組み込み向けのCが本職で、Windowsプログラムはほとんど経験がありません。
スレッド内でメッセージボックスを表示させることはWindowsプログラムではほとんどしな
いことなんでしょうか?
0098デフォルトの名無しさんNGNG
>>97
俺もあまり詳しくはないが、そこまでMessageBoxにこだわる必要はないのでは?
メッセージ出力用のダイアログクラスを作成して、そのクラスに親の位置を渡せば良いのでは
ないのかな
ダイアログクラスなら、OnInitDialog()で表示位置やサイズを変更すると簡単なんだけど。
意図していたことと違うかもしれないが、暫定的にしておいて、他のもっと重要なところに
パワーをかけた方が良いと思うよ
0099デフォルトの名無しさんNGNG
>>97
スレッドにはメッセージループを持つスレッドと、持たないスレッドがある。
WM_INITDIALOGはメッセージなわけだが・・・
0100デフォルトの名無しさんNGNG
>>97
Windowsでは、ウインドウはどれかのスレッドに属している、
つまりスレッドがウインドウを保持しているといっていい。
そして1つのウインドウは複数のスレッドに共有されることは無い。
ウインドウには親子関係があるがこれは同一スレッド内においてのみ有効
スレッドがウインドウを作った場合親ウインドウに別のスレッドのウインドウを
指定しても無効になる
メッセージボックスの場合、内部的にCenterWindowが呼ばれるわけだが、
親ウインドウがいないもしくは無効な為、ど真ん中に表示されてしまう
どうしてもと言うなら、試したこと無いので出来るかどうかわからないが
見えない親ウインドウをスレッド元のウインドウサイズにあわせて作って
おいてメッセージボックスを呼び出すとか
0101デフォルトの名無しさんNGNG
>>96
つまり、スクロールバーを表示させたくないってこと?
0102デフォルトの名無しさんNGNG
>>96
一応調べてみたらこういうのあったけど
ttp://www.codeproject.com/docview/resizableformview.asp
0103デフォルトの名無しさんNGNG
CStringArrayのサンプルプログラムが欲しいです。
参考ページでもいいのでお願いします。
0104デフォルトの名無しさんNGNG
>>103
別スレだけど
http://pc5.2ch.net/test/read.cgi/tech/1087929711/969
でCの宿題の回答にCStringArray使ってるね
0105デフォルトの名無しさんNGNG
>>104
コンパイルすらできない俺って・・・_| ̄|○
VC7ですが、助けてくださらんか?
01061/2NGNG
>>105
長くなって申し訳ないが、969さんのコード全部転載させてもらいますた。
あくまで例として載せてくれたみたいなので、宣言が抜けてたりしたのを
追加しただけです。

#include <afxwin.h>
#include <io.h>
#include <iostream>
using namespace std;

CStringArray arDstFileList;
CStringArray arSrcFileList;

void Read(CString& csFile)
{
CStdioFile readFile;;
CString csRead;
readFile.Open(csFile,CFile::modeRead);
CString csDstFile;
CString csSrcFile;
while (readFile.ReadString(csRead)){
csDstFile = csRead.Mid(0,csRead.Find(":"));
csSrcFile = csRead.Mid(csRead.Find(":") + 1,csRead.GetLength());
arDstFileList.Add(csDstFile);
arSrcFileList.Add(csSrcFile);
}
readFile.Close();
}
01072/2NGNG
void Move()
{
// ファイル有無(書き込み権チェック)
for (int i = 0;i < arSrcFileList.GetSize();i++){
if (0 != _access(arSrcFileList.GetAt(i),6)){
throw new CFileException();
}
}
// ファイルの移動
for (i = 0;i < arSrcFileList.GetSize();i++){
if (0 == ::MoveFile(arSrcFileList.GetAt(i),_T("C:\\temp\\") + arDstFileList.GetAt(i))){
throw new CFileException();
}
}
}

main()
{
try{
Read(CString("C:\\list.dat"));
Move();
}
catch(CException* pE){
pE->Delete();
cerr << _T("ERROR") << endl;
}
}
0108105NGNG
>>106
VCを初めて3日目なんで、こういうコードを載せてもらった場合、
どうやってスケルトン?(でしたっけ)を作るかわかりません。
MFCアプリケーションで作ればいいのでしょうか?
0109105NGNG
>>106
サンプルコードありがとうございました。
お礼が遅れて、すみません。
0110デフォルトの名無しさんNGNG
>>105
上のコードだとMFCとは言ってもMFCの中の
CStringArrayを使うだけで、中身はコンソールプログラム
だから(簡単に書くとコンソールプログラムはmainから
始まり、ウィンドウズプログラムはWinMainから始まる)
とりあえず、Win32コンソールプロジェクトで作成する。
で、CStringArrayを利用するにはMFCをリンクする必要が
あるのでプロジェクトのプロパティで「MFCの使用」を
「共有DLLでMFCを使用する」または「スタティックライブラリ
でMFCを使用する」に設定する。
始めて3日だと、リンクとかDLLとかスタティックとか言われても
わけわからないだろうけど、MSDNにも情報があるのでこつこつ
やってちょ。
0111105NGNG
>>110
がんばってコンパイルはとおりましたが、エラーが出て実行できませんでした。
もっと勉強します。
0112デフォルトの名無しさんNGNG
スプラッシュウインドウとしてメッセージを表示させるだけの
ダイアログにスタティックウインドウを貼り付けただけのウインドウを作りました
CWinApp::InitInstance中で作成、表示させようとするとウインドウ自体は
表示されるのですがスタティックコントロールのメッセージが表示されません。
メッセージはInitInstanceの関数を抜けたあとなら表示されるので
ただ単純に再描画の為のメッセージを受け取れていないだけだと思うのですが
InitInstance中にメッセージポンプ入れるなど色々試してみましたが思うように
表示されません。

今は、別スレッド化してメッセージの表示は出来ていますが
出来たら単一スレッドで動かしたいです。何かよい方法をご存知の方いらっしゃったら
教えてください

0113デフォルトの名無しさんNGNG
質問なのでage
0114デフォルトの名無しさんNGNG
>>113
これはダメかもわからんな
0115デフォルトの名無しさんNGNG
>>105
そっかぁ。もっと簡単な例だせばよかたーYO。
ごめん。
MFCの配列クラスはCStringArrayとかCUIntArrayとか
いっぱいあるけど、テンプレートというのを覚えると、
CArray<CString>、CArray<UINT> とCArrayクラステンプレート
だけ覚えると何でも作れるようになるYO。
その場合でもよく使うのは、Add、GetAt、GetSizeとかで
その他のも使ってるうちに覚えてくる。

#include <afxwin.h>
#include <stdio.h>

int main(void)
{
CStringArray ar;
ar.Add("あ");
ar.Add("い");
ar.Add("う");

printf("配列の要素数は %d コです。\n", ar.GetSize());

for (int i = 0; i < ar.GetSize(); ++i) {
printf("配列の %d 番目の 要素は %s です。\n", i, ar.GetAt(i));
}

return 0;
}
0116デフォルトの名無しさんNGNG
つーか始めて三日でなんでCStringArrayなのか分からない。
まずCString、そのうちCArrayって感じだと思うが。それぞれの
概念が理解できていれば、Arrayの仲間についても自然と分かる
はずだし。
0117105NGNG
>>115
ありがとうございます。
なんとなく、わかりました。
何でも作れるようになる・・・素晴らしい言葉ですね。
頑張ってマスターします。
今後とも宜しくお願いします!
0118デフォルトの名無しさんNGNG
素直にvector使おうよ…
0119デフォルトの名無しさんNGNG
>>118
MFCで作っている限りにおいてはvectorを使用するよりも
CStringArrayのほうが利点が多い
0120デフォルトの名無しさんNGNG
漏れもMFC使ってる分にはSTL使わないなぁ
0121105NGNG
>>118
vectorを使うとCStringArrayよりいいのでしょうか?
0122デフォルトの名無しさんNGNG
>>121
CString使うなら、CStringArrayで問題ない。
0123151NGNG
>>122
逆にstringだとvectorですか?
0124デフォルトの名無しさんNGNG
MFCでコンテナとして使うだけならデバッグ性能やシリアライズが出来る
CStringArrayが良い
アルゴリズム使う場合はstlだけどね
0125デフォルトの名無しさんNGNG
該当するものがなければvectorなり使うしかない。
0126デフォルトの名無しさんNGNG
>>125
該当するものとはどういう意味ですか?
0127デフォルトの名無しさんNGNG
ちなみに、VCでstl使うならstlportの方が良いよ
0128デフォルトの名無しさんNGNG
スレッドを使うプログラムを作ったのですが、
スレッドからダイアログにメッセージをセットしようとするとアサートします。
スレッドが怪しいのですが、
UINT thread(LPVOID pParam)で作って
CTestdlg;

として、dlg.GetDlgItem(IDC_EDIT1)->SetWindowText(msg);

では駄目なのでしょうか?
どうすればセットできますか?
0129デフォルトの名無しさんNGNG
>>127
だったらBoostでいい
0130デフォルトの名無しさんNGNG
>>129
俺も使ってるけどねboost
ただ敷居がちと高い
0131112NGNG
もう少し詳しく書いてくれたら教えるよ
0132デフォルトの名無しさんNGNG
>>128だった
0133デフォルトの名無しさんNGNG
>>110
便乗で申し訳ありませんが、
1.「共有DLLでMFCを使用する」
2.「スタティックライブラリでMFCを使用する」

1.2はどうちがうのでしょうか?
0134デフォルトの名無しさんNGNG
>>129
boostはstl実装じゃないじゃん。
0135デフォルトの名無しさんNGNG
libをリンクするか、dllを使うかの違い。
0136デフォルトの名無しさんNGNG
>>132
ダイアログベースでスレッドをコールするようにしているのですが、
そのクラスへ Cクラス dlg
として、dlg.GetDlgItem(IDC_EDIT1)->SetWindowText(msg)とすると
アサートします。
コンパイルは通るのですが。
0137デフォルトの名無しさんNGNG
>>136
ワーカスレッドで作ってるから。
0138デフォルトの名無しさんNGNG
>>137
他にどんな方法があるのでしょうか?
0139112NGNG
>>136
う〜ん、わからんw
まずスレッドを生成している場所はどこ?
生成方法は?
0140112NGNG
ついでにそのダイアログクラスは、元のダイアログなの
関係が上手くつかめない
0141デフォルトの名無しさんNGNG
>>138
ユーザーインターフェイススレッド
0142デフォルトの名無しさんNGNG
>>139
生成場所はダイアログで実行される関数内です。
CWinThread *p_thread = ::AfxBeginThread(Thread, this);
こんな感じでThread関数を呼び出します。
UNIT Thread(LPVOID pParam)
ワーカスレッドを真似てみたのですが。。怪しいです
0143デフォルトの名無しさんNGNG
>>140
ダイアログは一つです。クラスも一つです。(スレッドはクラスの宣言をしてません)

>>141
聞いたことはありますが、使ったことはありませんでした。
ちょっと調べてみます。
0144デフォルトの名無しさんNGNG
あーなるほど
スレッドに元のダイアログのポインタを引数として渡して
そこからダイアログの子ウインドウに何かやっているってことか
0145デフォルトの名無しさんNGNG
アサートしているのはどこ、GetDlgItemのウインドウハンドルがNULLとかかな?
0146デフォルトの名無しさんNGNG
>>144
そんな感じでしようとしてましたができませんでした。
0147デフォルトの名無しさんNGNG
生成場所のダイアログで実行される関数って何?
0148デフォルトの名無しさんNGNG
使用で
「マルチスレッドに対応すること」
と書かれていた場合、どんな風に実装すればいいのでしょうか?
0149デフォルトの名無しさんNGNG
またすごい質問がきたな。w
0150デフォルトの名無しさんNGNG
>>145
多分そうです。ウィンドウハンドラがNULLです。
0151138NGNG
>>147
OnOK()です。
0152デフォルトの名無しさんNGNG
>>148
同時に同じリソースにアクセスされても整合性が取れる実装ってことだね
ライブラリなんかを作る場合、その部分をしっかり作っておかないと不味い
0153138NGNG
ユーザインタフェーススレッドはこのコール方法で合っていますか?

CSubThread *pThread = (CSubThread*)AfxBeginThread(RUNTIME_CLASS(CSubThread),THREAD_PRIORITY_NORMAL, 0, 0);
pThread->m_bAutoDelete=FALSE;
pThread->ResumeThread();

これでCWinThreadの派生クラスを作成しましたが、これでよいのでしょうか?
複数のスレッドにするにはその数分クラスを作成しないといけないのですか?
0154デフォルトの名無しさんNGNG
OnOkか・・・ちなみに、そのコントロールは存在しているよね
0155138NGNG
>>154
はい。デフォルトのまま置いてあります。
0156デフォルトの名無しさんNGNG
>>153
言っておくけどユーザインターフェーススレッドはそのスレッドでウインドウを
マネージしたい場合(メッセージキューを作って云々ってことね)に
作るスレッドなので138の今回の目的のためには使えないんじゃないかと思う

なぜならユーザスレッドとワーカスレッドなんてのはMFCの上だけで存在するものだし
多分もっと根本的な問題だと思うけど
0157デフォルトの名無しさんNGNG
まさかとは思うけど
OnOKの実装ってそのままにしていない?
CDialog::OnOKのディフォルトって内部でEndDialogを呼び出すけど。。。
0158デフォルトの名無しさんNGNG
>>155
たぶんソース張ってもらったほうが早いんで、ソース張ってくれます?
スレッドの部分だけでいいんで。
0159デフォルトの名無しさんNGNG
ちなみに今ダイアログでこんなの作ってみたが問題なく動いたよ
UINT ThreadFunc( LPVOID lpVal )
{
CThreadTEstDlg *pDlg = (CThreadTEstDlg *)lpVal;
pDlg->GetDlgItem( IDC_EDIT1 )->SetWindowText( "テスト" );
return 0;
}

void CThreadTEstDlg::OnOK()
{
// TODO: この位置にその他の検証用のコードを追加してください
CWinThread *pThread = AfxBeginThread( ThreadFunc, this );
//CDialog::OnOK();
}
0160158NGNG
>>159
漏れも試したら普通に動いたんで、なにか根本的に間違えてると思う。
0161138NGNG
こんな感じです。

void CTestDlg::OnOK()
{
threadflag = 1;

CWinThread *p_thread = ::AfxBeginThread(Thread, this);
//CDialog::OnOK();
}

UNIT thread(LPVOID pParam)
{
CTest dlg;
CString msg;

while(threadflag){
// 処理
//msgにメッセージを格納
}

dlg.GetDlgItem(IDC_EDIT1)->SetWindowText(msg);
}

threadflagがグローバル変数のフラグで
こいつは本当はMutexLockとかしてもう少し複雑に処理してますが、
流れはこんな感じです。
0162デフォルトの名無しさんNGNG
あぁ、やっぱり。。。。
0163デフォルトの名無しさんNGNG
>CTest dlg;
ここ
0164デフォルトの名無しさんNGNG
いやな予感はしていたが・・・
0165デフォルトの名無しさんNGNG
じゃ、後はよろしく
俺は寝ます・・・
0166138NGNG
>>162-163
直りました。。
ありがとうございました。
0167デフォルトの名無しさんNGNG
>>106
これをstl使って書いたコードが見たいのですが、誰か書いてくれませんか?
0168デフォルトの名無しさんNGNG
>>167
>115のでもいいなら...

#include <vector>
#include <string>
#include <stdio.h>
using namespace std;

int main(void)
{
vector<string> vec;
vec.push_back("あ");
vec.push_back("い");
vec.push_back("う");

printf("配列の要素数は %d コです。\n", vec.size());

for (int i = 0; i < vec.size(); ++i) {
printf("配列の %d 番目の 要素は %s です。\n", i, vec[i].c_str());
}

return 0;
}
0169つづきNGNG
string、vectorがSTLで定義されているクラスです。
for文のところは
int i;
vector<string>::const_iterator iter;
for (i = 0, iter = vec.begin(); iter != vec.end(); ++iter, ++i) {
printf("配列の %d 番目の 要素は %s です。\n", i, iter->c_str());
}
でもOK。これはSTLのイテレータという機能を使った方法。(イテレータは自分で勉強してちょ)

0170デフォルトの名無しさんNGNG
>>168
深夜にありがとう。
がんがりまっす
0171デフォルトの名無しさんNGNG
>>106
これさー、datのSTARTとENDそのまま読み込むからエラーになるんだよ。
そりゃ、コンパイル通っても実行はできんさw
0172デフォルトの名無しさんNGNG
質問です
CDialogBar上に、スピンボタンを配置しました
CDialogBarは、派生クラスを作らないとMSDNにあったのでコントロールのハンドリングは
すべてCMainFrame上に持ってきています。
このようにすると、スピンコントロールがどうしてもEnableになりません
これはどういうことでしょうか
環境はVC6sp6です
017397NGNG
メッセージボックスっぽいものを自作することで
解決しました。
回答をくれた皆さんありがとうございました。
0174デフォルトの名無しさんNGNG
>>172
CDialogBar::OnUpdateCmdUIをオーバーロードしないとあかんらしいです。
うちはVS.NETだけど、たぶん同じだと思います。
0175デフォルトの名無しさんNGNG
MFCでコマンドライン引数を渡したいです。

m_lpCmdLineを使うのはわかったのですが、サンプル欲しいです。

渡したいコマンドライン引数は
「xxx.exe -a:c:\hoge.txt -b:c:\poko.txt」
MFCのダイアログベースで制作しているアプリです。
引数を他のcppファイルで受け取って、変数に入れて使用したいです。

宜しくお願い致します。

0176デフォルトの名無しさんNGNG
>>174
回答ありがとうございます
つまり、CDialogBarを派生させないといけないと言うことですね

問題のおきているソースは、かなりでかいプロジェクトでCDialogBarのほとんどの
コマンドハンドラーはCMainFrameに記述されています。
そのためCDialogBarの派生クラスに持っていくのは結構手間がかかってしまいます。

ためしに新規にダイアログバーを持つSDIアプリを作ってみたところスピンコントロールは
問題なくEnableになっていました。
MFCのソースを解析してみたところ、通常ボタンコントロール以外はGet(DLGC_BUTTON以外)
Enableになるように見受けられるのでもう一度どういう原因でDisableになるか調べてみようと思っています
0177デフォルトの名無しさんNGNG
途中で送信してしましました

・・・・
問題なくEnableになっていました。
MFCのソースを解析してみたところ、ジェネリックボタンコントロール以外は
(WM_GETDLGCODEの戻り値がDLGC_BUTTON以外)
Enableになるように見受けられるのでもう一度どういう原因でDisableになるか
調べてみようと思っています

0178デフォルトの名無しさんNGNG
ついでだから回答w
>>175
MFCの場合引数はCCommandLineInfoを継承したクラスを生成して
ParseParam関数をオーバーライドして引数を解析するというのが一般的です。
(といいつつあまり一般に利用されていないけど)
今回の引数は形式がウインドウズの標準と違うため、独自に文字列の
切り離しなどを入れるしかありません-をオプションの識別子としているのであれば
-を取ってコロンを境に前後に文字列を分ける等の処理を入れれば良いでしょう

さてそれを他のcpp(多分他のクラスということでしょうか)に渡すのであれば
ab切り出したそれぞれの文字列変数(CStringなど)を別のクラスに渡せばいいと思います
0179デフォルトの名無しさんNGNG
>>175
>>32
0180デフォルトの名無しさんNGNG
すいません。
ちょっと質問です。

今、巷の普通の本屋さんで売っているWindowsプログラムの本は大体Visual C++の
本です。
それでそういう本には、「ウイザードで勝手に作られるんで、カスタマイズしたいときは
ここをいじってください」としか書いてなくて、なぜそこをいじればいいのか、プログラムが
どういう流れになっているのか全く分かりません。

結局、SDKの方が分かりやすいと思い、まずはそっちをやることにしました。
みなさんはどうやってMFCを勉強されたのでしょうか?
もっと良い入門書があるのでしょうか?
0181デフォルトの名無しさんNGNG
>>180
どの関数がどのクラスのメンバか意識するようにしたら理解できた。
関数名しか書いてなくても、クラス名::関数名 っていうようにして憶える。
0182デフォルトの名無しさんNGNG
>>180
> それでそういう本には、「ウイザードで勝手に作られるんで、カスタマイズしたいときは
> ここをいじってください」としか書いてなくて、

まずはそこから始めて、具体的な成果物を作らないことにはモチベーションが
持続しないと思うが。体系なんてものは大きすぎてなかなか理解できるもので
ないし、とにかく何か動くものを作れるようになることが先。手段は後で良いんだ
よ。まず「何を作りたいか」、「どういう動きをさせたいか」が大切。それに沿って
どうすれば良いかを調べていく。経験を重ねれば、下層にあるものがだんだん
見えてくるし、それからシステムの学習に入ればいい。

もちろん、CやC++の基礎がないようなレベルだったら話は別。そういった
言語レベルの基礎知識は身に付いてないとVCプログラミングは難しい。
0183デフォルトの名無しさんNGNG
>>180
そんなあなたに
翔泳社の標準講座MFC ハーバートシルト著
0184デフォルトの名無しさんNGNG
>>180
MFC→ウィザードが生成したものをいじる
SDK→猫からソースパクっていじる

結局同じ
0185デフォルトの名無しさんNGNG
>>180
食わず嫌いせずとりあえず一番高いものに食いついて、消化できなくて吐き出して、
高い金払って食って吐いて、高い金払って食って吐いて、
食って吐いて、食って吐いて、食って吐いて……と繰り返しあがき続けていたら、
いつの間にかMFCでもSDKでも問題なく使えるようになり、物も食えるようになっていた。

しかし、そこに行き着くまでに消費した書籍代は…… _| ̄|○
0186デフォルトの名無しさんNGNG
本来、クラスライブラリはその中の構造に関する知識を必要としな
いものだ。したがって
>なぜそこをいじればいいのか
>プログラムがどういう流れになっているのか
なんて気にするな。
と考える俺は少数派だと自覚しております。
0187デフォルトの名無しさんNGNG
>>185
途中で降りたらベット丸損だぞ
本と同じ重さの札束を狙う大博打ってとこを忘れんな
0188デフォルトの名無しさんNGNG
void hoge(void)
{
  CPen myPen;


  myPen.DeleteObject(); ←これいるんですか?
  Delete myPen;      ←これもいるんですか?
}

CPenってスコープ外れる時に、この辺やってくれないの?
0189デフォルトの名無しさんNGNG
>  Delete myPen;      ←これもいるんですか?

こんなのいれたらコンパイルとおらねぇよ。
0190デフォルトの名無しさんNGNG
>>189
myPen.DeleteObject();
これ、必須ですか?
0191デフォルトの名無しさんNGNG
msdnより、

1.スタック フレーム上にグラフィック オブジェクトを定義します。CreatePen など、それぞれの型固有の作成関数を使って、オブジェクトを初期化します。コンストラクタでオブジェクトを初期化することもできます。
 1 段階で作成する方法と、2 段階で作成する方法については以下に説明します。
2.オブジェクトを現在のデバイス コンテキストに選択し、前に選択した古いグラフィック オブジェクトを保存します。
3.現在のグラフィック オブジェクトを使い終わったら、古いグラフィック オブジェクトをデバイス コンテキストに選択し直して、状態を復元します。
4.フレームに割り当てられたグラフィック オブジェクトは、スコープからはずれたときに自動的に削除されます。

これ見て意味わからんかったら再度質問しろ。
■ このスレッドは過去ログ倉庫に格納されています