MFC ActiveX Control "EDIT" の背景色の設定を教えて

解決


げんさん  2009-01-29 02:59:32  No: 69522

VC++ は初心者です。

MFC ActiveX Control で テキストボックスのOCXを作りたいのですが、
::OnDraw に pdc->SetBkColor(GetBackColor());をいれても
背景色に変化はありません。
背景色の設定を教えてください

// RsTextCtl.cpp : CRsTextCtrl ActiveX コントロール クラスのインプリメンテーション

#include "stdafx.h"
#include "RsText.h"
#include "RsTextCtl.h"
#include "RsTextPpg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

IMPLEMENT_DYNCREATE(CRsTextCtrl, COleControl)

/////////////////////////////////////////////////////////////////////////////
// メッセージ マップ

BEGIN_MESSAGE_MAP(CRsTextCtrl, COleControl)
  //{{AFX_MSG_MAP(CRsTextCtrl)
  // メモ - ClassWizard はメッセージ マップのエントリを追加または削除します
  //    この位置に生成されるコードを編集しないでください!
  //}}AFX_MSG_MAP
  ON_MESSAGE(OCM_COMMAND, OnOcmCommand)
  ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// ディスパッチ マップ

BEGIN_DISPATCH_MAP(CRsTextCtrl, COleControl)
  //{{AFX_DISPATCH_MAP(CRsTextCtrl)
  DISP_PROPERTY_NOTIFY(CRsTextCtrl, "DisplayText", m_displayText, OnDisplayTextChanged, VT_BSTR)
  DISP_PROPERTY_EX(CRsTextCtrl, "Text", GetText, SetText, VT_BSTR)
  DISP_PROPERTY_EX(CRsTextCtrl, "BackColor", GetBackColor, SetBackColor, VT_COLOR)
  DISP_DEFVALUE(CRsTextCtrl, "Text")
  //}}AFX_DISPATCH_MAP
END_DISPATCH_MAP()

/////////////////////////////////////////////////////////////////////////////
// イベント マップ

BEGIN_EVENT_MAP(CRsTextCtrl, COleControl)
  //{{AFX_EVENT_MAP(CRsTextCtrl)
  //}}AFX_EVENT_MAP
END_EVENT_MAP()

/////////////////////////////////////////////////////////////////////////////
// プロパティ ページ

// TODO: プロパティ ページを追加して、BEGIN 行の最後にあるカウントを増やしてください。
BEGIN_PROPPAGEIDS(CRsTextCtrl, 1)
  PROPPAGEID(CRsTextPropPage::guid)
END_PROPPAGEIDS(CRsTextCtrl)

/////////////////////////////////////////////////////////////////////////////
// クラス ファクトリと guid を初期化します

IMPLEMENT_OLECREATE_EX(CRsTextCtrl, "RSTEXT.RsTextCtrl.1",
  0x978cfb2b, 0x8fd6, 0x4217, 0xb5, 0x4f, 0x33, 0x7, 0x3, 0x62, 0xe6, 0x55)

/////////////////////////////////////////////////////////////////////////////
// タイプ ライブラリ ID とバージョン

IMPLEMENT_OLETYPELIB(CRsTextCtrl, _tlid, _wVerMajor, _wVerMinor)

/////////////////////////////////////////////////////////////////////////////
// インターフェイス ID

const IID BASED_CODE IID_DRsText =
    { 0xfffec08c, 0xffe3, 0x492b, { 0xb6, 0x5d, 0x38, 0x3f, 0xf8, 0x65, 0x67, 0x79 } };
const IID BASED_CODE IID_DRsTextEvents =
    { 0xe51cfec6, 0x32dc, 0x4374, { 0x8d, 0xfe, 0xe3, 0xac, 0x63, 0x37, 0x52, 0x17 } };

/////////////////////////////////////////////////////////////////////////////
// コントロールの型情報の制御

static const DWORD BASED_CODE _dwRsTextOleMisc =
  OLEMISC_ACTIVATEWHENVISIBLE |
  OLEMISC_SETCLIENTSITEFIRST |
  OLEMISC_INSIDEOUT |
  OLEMISC_CANTLINKINSIDE |
  OLEMISC_RECOMPOSEONRESIZE;

IMPLEMENT_OLECTLTYPE(CRsTextCtrl, IDS_RSTEXT, _dwRsTextOleMisc)

/////////////////////////////////////////////////////////////////////////////
// CRsTextCtrl::CRsTextCtrlFactory::UpdateRegistry -
// CRsTextCtrl のシステム レジストリのエントリを追加または削除します 

BOOL CRsTextCtrl::CRsTextCtrlFactory::UpdateRegistry(BOOL bRegister)
{
  // TODO: コントロールがアパートメント モデルのスレッド処理の規則に従っていることを
  // 確認してください。詳細については MFC のテクニカル ノート 64 を参照してください。
  // アパートメント モデルのスレッド処理の規則に従わないコントロールの場合は、6 番目
  // のパラメータを以下のように変更してください。
  // afxRegApartmentThreading to 0.

  if (bRegister)
    return AfxOleRegisterControlClass(
      AfxGetInstanceHandle(),
      m_clsid,
      m_lpszProgID,
      IDS_RSTEXT,
      IDB_RSTEXT,
      afxRegApartmentThreading,
      _dwRsTextOleMisc,
      _tlid,
      _wVerMajor,
      _wVerMinor);
  else
    return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
}

/////////////////////////////////////////////////////////////////////////////
// CRsTextCtrl::CRsTextCtrl - コンストラクタ

CRsTextCtrl::CRsTextCtrl()
{
  InitializeIIDs(&IID_DRsText, &IID_DRsTextEvents);

  // TODO: この位置にコントロールのインスタンス データの初期化処理を追加してください
  m_backColor = RGB(255,255,255);   
}

/////////////////////////////////////////////////////////////////////////////
// CRsTextCtrl::~CRsTextCtrl - デストラクタ

CRsTextCtrl::~CRsTextCtrl()
{
  // TODO: この位置にコントロールのインスタンス データの後処理用のコードを追加してください
}

/////////////////////////////////////////////////////////////////////////////
// CRsTextCtrl::OnDraw - 描画関数

void CRsTextCtrl::OnDraw(
      CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{

//    pdc->SetBkColor( RGB( 255, 0, 0 ) );  // 文字の部分の背景色設定
//      pdc->SetTextColor(RGB( 255, 0, 0 ));

//    pdc->SetBkColor(GetBackColor());

    DoSuperclassPaint(pdc, rcBounds);
}

/////////////////////////////////////////////////////////////////////////////
// CRsTextCtrl::DoPropExchange - 永続性のサポート

void CRsTextCtrl::DoPropExchange(CPropExchange* pPX)
{
  ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
  COleControl::DoPropExchange(pPX);

  // TODO: 継続表示属性を持つ各カスタム プロパティ用の PX_ 関数の呼び出しを追加してください
  PX_String(pPX, _T("DisplayText"), m_displayText);
    PX_Color(pPX,_T("BackColor"),m_backColor);   

}

/////////////////////////////////////////////////////////////////////////////
// CRsTextCtrl::OnResetState - コントロールのプロパティ値をリセット

void CRsTextCtrl::OnResetState()
{
  COleControl::OnResetState();  // DoPropExchange を呼び出してデフォルト値にリセット

  // この位置にコントロールの状態をリセットする処理を追加してください
}

/////////////////////////////////////////////////////////////////////////////
// CRsTextCtrl::PreCreateWindow - CreateWindowEx のパラメータを修正

BOOL CRsTextCtrl::PreCreateWindow(CREATESTRUCT& cs)
{
  cs.lpszClass = _T("EDIT");
//  cs.dwExStyle =  DS_3DLOOK;
  cs.style =WS_VISIBLE | WS_CHILD | WS_BORDER | ES_LEFT; // | DS_3DLOOK;
  return COleControl::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CRsTextCtrl::IsSubclassedControl - サブクラス化されたコントロール

BOOL CRsTextCtrl::IsSubclassedControl()
{
  return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CRsTextCtrl::OnOcmCommand - コマンド メッセージのハンドル

LRESULT CRsTextCtrl::OnOcmCommand(WPARAM wParam, LPARAM lParam)
{
#ifdef _WIN32
  WORD wNotifyCode = HIWORD(wParam);
#else
  WORD wNotifyCode = HIWORD(lParam);
#endif

  // TODO: この位置にスイッチ ステートメントで wNotifyCode を処理するコードを追加してください

  return 0;
}

void CRsTextCtrl::OnDisplayTextChanged() 
{
  // TODO: ハンドラ コードを追加してください
  char Msg[64];
  sprintf (Msg,"TextChanged%s",NULL);
  MessageBoxA(NULL,Msg,"確認",MB_OK);

  SetModifiedFlag();
}

BSTR CRsTextCtrl::GetText() 
{
  CString strResult;
//  char Msg[64];
//  CString Msg;
  // TODO: ここにプロパティ ハンドラを追加してください
//  Msg = "GetText";

  
//  sprintf (Msg,"GetText%s",NULL);
  GetWindowText(strResult);

//  MessageBoxA(NULL,Msg,"確認",MB_OK);

  
  return strResult.AllocSysString();
}

void CRsTextCtrl::SetText(LPCTSTR lpszNewValue) 
{
  // TODO: ここにプロパティ ハンドラを追加してください

//  char Msg[64];
//  sprintf (Msg,"SetText=%s",lpszNewValue);
//  MessageBoxA(NULL, Msg,"確認",MB_OK);

  SetWindowText(lpszNewValue);
  SetModifiedFlag();
}

OLE_COLOR CRsTextCtrl::GetBackColor() 
{
  // TODO: ここにプロパティ ハンドラを追加してください

  return m_backColor;
}

void CRsTextCtrl::SetBackColor(OLE_COLOR nNewValue) 
{
  // TODO: ここにプロパティ ハンドラを追加してください

  char Msg[64];
  sprintf (Msg,"SetBackColor=%s",NULL);
  MessageBoxA(NULL, Msg,"確認",MB_OK);

    m_backColor=nNewValue;   

  SetModifiedFlag();
}


  2009-01-29 19:33:22  No: 69523

http://support.microsoft.com/kb/148242/ja

これかな?
昔Staticコントロールで似たようなこと記憶があるのですが
忘れてしまいました。


げんさん  2009-01-30 10:37:14  No: 69524

初期の色は変わったが、
SetTextColor(NULL,m_backColor)では変わらなかった。
OnOcmCtlColorが実行されるタイミングが良く分からないが、
SetBackColorでRedrawWindow();を実行したらOnOcmCtlColor
が実行され、背景色が変わったのでとりあえず解決(^^;)
OnOcmCtlColorが実行される関数等あれば教えてください。


  2009-01-31 18:52:25  No: 69525

VC6ならソースを提供できそうな気がしますが
環境がよく分からないので保留にしますね。
2003ではうまくビルドできなかったので。

私の場合はBackColorとForeColorだけだったので
ストックプロパティを使ってGetBackColor()と
GetForeColor()を使って実装したので、質問の部分の
呼び出しについてはよく分かりません。

OCM_CTLCOLORがWM_CTLCOLORのActiveX版相当と考えると
InvalidateRect()あたりを使ってもうまくいくのでは
ないでしょうか?


げんさん  2009-02-01 04:53:20  No: 69526

む さん  ありがとう御座います。m(_ _)m
VB6.0のテキストボックスで数値を扱う時,"#,###,##0","#,###,##0円","####年##月##日" などを編集して表示したりするのですが、入力があると数値に戻さないといけなかったりするので、VC++でOCXを作ろうとしているのですが、
なかなか面倒なものですね(^^;)
InvalidateRect();ためしてみがしたが、HWIND や  RECT のパラーメタ
が必要らしくSetForeColorの中でHWIND,RECTが無いのでRedrawWindow()
にしました。ネット検索や参考書を探っていますが  HWIND  では良く
悩まされています。(^^;)


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加