- ベストアンサー
ClistBoxでオーナードローについての質問
supersonicの回答
MSDNライブラリに載っている例はご覧になりましたか? http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vclib/html/_mfc_clistbox.3a3a.drawitem.asp 描画の仕方は何となくこれでイメージがつかめると思います。 どういうものを描画したいのか、 文章だけでは読み取るのが難しいですが、 多分オーナードローでいいと思います。 おそらく誤解されている点に限って申しますと、 選択に関しては、選択されている部位の色が変わったりとか、 フォーカスの枠線が表示されたりという部分も、 オーナードローの場合、自分でコーディングすることになります。 ですので、リストボックスのアイテム上でクリックなどをしても、 描画していない以上は、画面上ではわかりません。 描画するべきアイテムがあるときにDrawItemが呼ばれるわけですが、 DRAWITEMSTRUCT構造体のメンバであるitemActionやitemStateの値で条件分岐し、 描画するべきアイテムがどういう状態にあるかによって、 塗りつぶす色などを場合分けしなくてはなりません。 この辺は、MSDNの例を見るなり、 実際にこのコードをコンパイルして動きを見れば意味がわかると思います。 また、描画する範囲ですが、 DRAWITEMSTRUCT構造体のメンバであるRECT構造体rcItemに入っています。 この座標を文字や背景、選択の枠などを描画する位置を決めるのに使います。 AddStringで追加した文字列を参照するには、 lpDrawItemStruct->itemDataで合っています。 私も特に詳しいわけではないので、こんな説明しかできません。
関連するQ&A
- リストボックスのオーナードローでInsertStringした文字列の取得
ダイアログボックスの上にリストボックスを貼り付け、そのリストボックスを各行ごとに色を変て表示させることにトライしています。 なんとかかんとか調べて、 1.リストボックスのリソースで「Owner Draw=固定」に設定変更した。 2.そのリストボックスを持つクラスのウィンドウメッセージ WM_DRAWITEM WM_MEASUREITEM にハンドラを追加した。 3.以下の様にハンドラを記述した。 void COwnerTestDlg::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct) { lpMeasureItemStruct->itemHeight = 10/*1行の高さを設定*/; CDialog::OnMeasureItem(nIDCtl, lpMeasureItemStruct); } void COwnerTestDlg::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct) { CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC); pDC->FillSolidRect(&lpDrawItemStruct->rcItem, RGB(0,0,0)/*背景の色*/); pDC->SetBkColor(RGB(0,0,0)/*文字の後ろの色*/); pDC->SetTextColor(RGB(255,255,255)/*文字の色*/); pDC->TextOut(lpDrawItemStruct->rcItem.left, lpDrawItemStruct->rcItem.top, (char*)lpDrawItemStruct->itemData/*行に書かれた文字列*/); } 4. CListBox* wp = (CListBox*)GetDlgItem(IDC_LIST1); wp->InsertString(-1,"ADDED"); とやり、うまく表示されました。 ここまでは良かったのですが、 次に、4.のところを char wbuf[256]; strcpy(wbuf,"ADDED"); wp->InsertString(-1,wbuf); とやったら文字化け(?)の様な、ちゃんと表示してくれなくなってしまいました。何がいけないのでしょうか?
- ベストアンサー
- C・C++・C#
- VS2008のMFCのTextOutについて
毎度、お世話になります。 Windows7でVS2008のMFCのFormView形式でプログラムしています。 OnButton5でTextOut文を実行していますが、最後の『pDC->TextOut(20,80,str)』 だけ表示されます。 但し、前の2個のpDC->TextOutの後にSleep(1)を追加しますと、全て表示できます。 Q1)Sleep(1)を追加しなくて、全てのTextOutが表示できる方法はありますか? ================================ void CMFCTHREADView::OnButton5(){ // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください CDC* pDC=this->GetDC(); int t_endB=999; str.Format("time=%d ms ",t_endB); pDC->TextOut(20,40,str); //これだけ表示されず。 //=============== str.Format("countX=%d ",countX); pDC->TextOut(20,60,str); //これだけ表示されず。 //=============== str.Format("countA=%d countB=%d ",countA,countB); pDC->TextOut(20,80,str); //これだけ表示されます。 //==================== } =================================== 以上、宜しくお願いします。
- ベストアンサー
- C・C++・C#
- 非クライアント領域への描画について
非クライアント領域に文字を書こうとしました。 以下の(2)では書けますが、(1)では書いてくれません。 CPaintDCはクライアント領域でないとダメなのですか? void CMainFrame::OnPaint() { CPaintDC dc(this); // 描画用のデバイス コンテキスト dc.TextOut(0,0,"こんにちは"); ・・・(1) CDC* pDC = GetWindowDC(); pDC->TextOut(100,0,"こんにちは"); ・・・(2) 環境 WIN98 VC++6.0 MFC
- ベストアンサー
- C・C++・C#
- CLRでのListBoxのオーナードローのやり方。
Visual C++のCLRでフォームアプリケーションを作っていて、ListBoxのオーナードローの方法がわからないので質問させてもらいました。 CLRでプログラミングしたことが無く書籍などを読んだこともなく見よう見まねで作っています。 やりたいことはとりあえず http://dobon.net/vb/dotnet/control/lbownerdraw.html にあることです。 サンプルプログラムはVBとC#でC++がありません。 MSDN(http://msdn.microsoft.com/ja-jp/library/system.windows.forms.listbox.drawitem.aspx)も同様でVBとC#のサンプルプログラムでC++がありませんでした。 とりあえず。 C#のサンプル----------------------------------------------- //DrawItemイベントハンドラ //項目を描画する private void ListBox1_DrawItem(object sender, System.Windows.Forms.DrawItemEventArgs e) { //背景を描画する //項目が選択されている時は強調表示される e.DrawBackground(); //文字を描画する色の選択 Brush b = null; if ((e.State & DrawItemState.Selected) != DrawItemState.Selected) { //選択されていない時 switch (e.Index % 3) { case 0: b = new SolidBrush(Color.Red); break; case 1: b = new SolidBrush(Color.Blue); break; case 2: b = new SolidBrush(Color.Green); break; } } else { //選択されている時はそのままの前景色を使う b = new SolidBrush(e.ForeColor); } //描画する文字列の取得 string txt = ((ListBox) sender).Items[e.Index].ToString(); //文字列の描画 e.Graphics.DrawString(txt, e.Font, b, e.Bounds); //後始末 b.Dispose(); //フォーカスを示す四角形を描画 e.DrawFocusRectangle(); } ----------------------------------------------- を参考にしてForm1に private: System::Void ListBox1_DrawItem(System::Object^ sender, System::Windows::Forms::DrawItemEventArgs^ e) { //背景を描画する //項目が選択されている時は強調表示される e->DrawBackground(); //文字を描画する色の選択 } と書いてみたのですが、そのあとどうすればよいかわかりません。 わかる方、回答お願いします。
- ベストアンサー
- C・C++・C#
- MFC VC++ 6.0 使用
CModel::OnDraw(CDC *pDC) { pDC->TextOut(0,0,"OK"); } というふうに OnDrawの中で pDC->TextOut()と 使って 実行画面に 文字を表示させることは できるのですが、例えば 自分が 追加した 関数 void CModel::On_Distance(){ } などで、実行画面に 文字をだしたいときは どうすればいいのでしょうか?pDC を 手に入れることが できるのであれば そのほうほう 教えてください。
- ベストアンサー
- C・C++・C#
- 問題です。
#include <stdio.h> short X1(char *,char *,char *); void X2(char *,short,short); void X3(char *,short,char *); void main(void) { char Str[][30]={"CDECDEGEDCDEC","CDE","AB"}; short Ret; Ret=X1(Str[0],Str[1],Str[2]); printf("Str[0] : %s\n", Str[0]); printf("Str[1] : %s\n", Str[1]); printf("Str[2] : %s\n", Str[2]); printf("Ret : %d\n", Ret); } short X1(char *pStr1,char *pStr2,char *pStr3) { short Len1,Len2,Len3; short Cnt1,Cnt2; short Ret = 0; for (Len1= 0;pStr1[Len1]!=0;Len1++); for (Len2= 0;pStr2[Len2]!=0;Len2++); for (Len3= 0;pStr3[Len3]!=0;Len3++); if (Len1<Len2 || Len2==0) return Ret; for (Cnt1=0; Cnt1<=Len1-Len2; Cnt1++){ for (Cnt2=0; Cnt2<Len2; Cnt2++){ if (pStr1[Cnt1+Cnt2]!=pStr2[Cnt2]) break; } if (Cnt2==Len2){ X2(pStr1,Cnt1+1,Len2); X3(pStr1,Cnt1+1,pStr3); Len1 += Len3-Len2; Cnt1 += Len3-1; Ret++; } } return Ret; } void X2(char *pStr, short Pnt, short Num) { short Cnt, Len; for (Len = 0; pStr[Len]!=0; Len++); for (Cnt = Pnt+Num-1; Cnt<=Len; Cnt++){ pStr[Cnt-Num] = pStr[Cnt]; } } void X3(char *pDst, short Pnt; char *pSrc) { short SrcLen, DstLen; short Cnt; for (SrcLen=0; pSrc[SrcLen]!=0; SrcLen++); for (DstLen=0; pDst[DstLen]!=0; DstLen++); for (Cnt=DstLen-1; Cnt>=Pnt-1; Cnt--){ pDst[Cnt+SrcLen]=pDst[Cnt]; } for (Cnt=0; Cnt<SrcLen; Cnt++){ pDst[Pnt+Cnt-1]=pSrc[Cnt]; } pDst[DstLen+SrcLen]=0; } というようなプログラムの出力結果はどうなるか?という問題ですが、Str[0]:ABABGEDABC, Str[1]:CDE, Str[2]:AB, Ret:3となるんですが、どうしてそうなるかが、全然分かりません。どなたか説明してもらえないでしょうか?お願いします。
- 締切済み
- C・C++・C#
- クライアント領域をCBitmapに取り込みたい
VC6.0MFCで クライアント領域(みたまま)を CBitmapに取り込みたいのですがどうすればよいのでしょうか? ためしにダイアログの領域をクリップボードに取り込むコード OnPaint書いたのですが真っ黒の画像しか取り込めていませんでした。 根本的に使うAPIが違うのでしょうか? void CCaptureDlg::OnPaint() { CPaintDC dc(this); // 描画用のデバイス コンテキスト CRect cr; GetClientRect(&cr); dc.TextOut(0,0,"テスト"); CDC* pDC = new CDC(); pDC->CreateCompatibleDC(&dc); CBitmap img; img.CreateCompatibleBitmap(pDC, cr.Width(), cr.Height()); OpenClipboard(); ::EmptyClipboard(); ::SetClipboardData(CF_BITMAP, img.GetSafeHandle()); ::CloseClipboard(); pDC->DeleteDC(); delete pDC; CDialog::OnPaint(); }
- ベストアンサー
- C・C++・C#
- 画像の印刷について
環境はWIN98 VC++6.0 MFCです。 初めて印刷に挑戦します。 TextOut()で書いた文字は印刷プレビューでちゃんと表示されましたが、以下のようにして取りこんだ画像を印刷プレビューで見ても何も表示されません。 どうしたら印刷できるようになりますか? void CXxxView::OnDraw(CDC* pDC) { CXxxDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: この場所にネイティブ データ用の描画コードを追加します。 CDC myDC; CBitmap myBMP; myBMP.LoadBitmap(IDB_BITMAP3); myDC.CreateCompatibleDC(pDC); CBitmap* oldBMP=myDC.SelectObject(&myBMP); pDC->BitBlt(10,10,60,100,&myDC,0,0,SRCCOPY); myDC.SelectObject(oldBMP); }
- ベストアンサー
- C・C++・C#
- VC++でのアイコン背景透過について
VC++2013 MFC環境です。 プログラムで○や×などの記号のアイコンを描画し、PNG,GIF,JPEGの形式でファイルに保存したいです。その時、アイコンの背景を透過したいのですがうまくいきません。 CDCクラスとCImageクラスを使用しアイコンの出力をしています。 背景透過について調べていくつか使えそうな関数があり試したのが、TransparentBltという関数で、デバイスコンテキストを二つ用意して、片方に記号を描画し、透過したい色を指定してもう片方にコピーすると指定した色が透過になる?と解釈しプログラム組みましたが結果は真っ黒の画像でした。 ここで完全に手が止まってしまい、質問させていただきます。 以下ソース CImage Image, image2; Image.Create( 50, 50, 24 ); image2.Create( 50, 50, 24 ); CDC* pDC = CDC::FromHandle( Image.GetDC( ) ); CDC* pdc2 = CDC::FromHandle( image2.GetDC( ) ); CRect rect( 0, 0, 50, 50 ); CPen BlackPen( PS_SOLID, 3, RGB( 0, 0, 0 ) ); CBrush WhitBrush( RGB( 255, 255, 255 ) ); CBrush BlackBrush( RGB( 0, 0, 0 ) ); pDC->FillRect( &rect, &WhitBrush ); pDC->SelectObject( &BlackPen ); pDC->SelectObject( &WhitBrush ); pDC->Ellipse( 5, 5, 45, 45 ); COLORREF col = Image.GetPixel( 0, 0 ); pdc2->TransparentBlt( 0, 0, 50, 50, pDC, 0, 0, 50, 50, col ); Image.SetTransparentColor( col ); image2.Save( L"c:\\icon\\maru.png" ); Image.ReleaseDC( ); image2.ReleaseDC( ); 他にも実装例があれば教えてください。 C++や画像生成に関しては経験がありません。
- ベストアンサー
- C・C++・C#
- リサイズで文字が消えちゃう
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { HDC hdc; char *str; switch (msg) { case WM_KEYDOWN: hdc = GetDC(hWnd); str = "キーダウンした"; TextOut(hdc,1,1,str,strlen(str)); ReleaseDC(hWnd,hdc); break; キーを押すと、LRESULT CALLBACK でウインドウに文字が 表示されるようにしました。 でも、この文字は別のウインドウに隠れて、再びウインドウが 表示された場合とかには消えています。 消えないようにするためにはどうしたらいいですか? void Swit(HWND hWnd) { HDC hdc; char *str; if (キーダウンのフラグがあったとして、それが true なら) { hdc = GetDC(hWnd); str = "キーダウンした"; TextOut(hdc,1,1,str,strlen(str)); ReleaseDC(hWnd,hdc); } return; } if ( ウインドウ再描画 == true ){ Swit() } というのを考えました。 LRESULT CALLBACK で、キーが押された場合にフラグを true にして ウインドウが再描画された場合にフラグをチェックして文字を 表示する という方法を考えたんだけど、これを BCC32 でコンパイル するためにはどういうソースを書いたらいいか分からないし、 もっといい方法があれば教えてください。
- ベストアンサー
- C・C++・C#
お礼
回答ありがとうございました。 回答を参考にして 理解を深めることが出来ました。 感謝しています。 難しいですね。 慣れるしかないのでしょうけど。 OnDrawItem DrawItem と複数の関数があったりして、 最初は、???状態です。