Задание региона для ActiveX.
От: buttercup  
Дата: 01.10.04 11:28
Оценка:
Привет всем.

Что-то у меня не получается задать регион для моего ActiveX контрола.

По WM_ERASEBACKGROUND рисую битмап... но правый вехний уголок битмапа мне нужно обрезать.

Т.о. имеем:



class ATL_NO_VTABLE CControl
{
public:
  CControl();

BEGIN_MSG_MAP(CControl)

  MESSAGE_HANDLER(WM_CREATE, OnCreate)
  MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
  CHAIN_MSG_MAP()
  DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()

public:
  HRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

  HRESULT OnDraw(ATL_DRAWINFO& di);
  LRESULT OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

private:
  HINSTANCE m_hInstance;

  HRGN m_rgn_bg;
  POINT m_wnd_rgn_points[6];
  HBITMAP m_bmp_bg;
};


А вот реализация:



CControl::CControl()
: m_hInstance(_AtlBaseModule.GetModuleInstance())
{
  m_bWindowOnly = true;

  m_bmp_bg = LoadBitmap(m_hInstance,MAKEINTRESOURCE(IDB_BG));
  assert(m_bmp_bg);
  if (m_bmp_bg)
  {
    // Считаем размер битмапа
    BITMAP bmp;
    ::GetObject(m_bmp_bg,sizeof(BITMAP),&bmp);
    RECT rc = {0,0,rc.left+bmp.bmWidth,rc.top+bmp.bmHeight};
    // Обрезаю уголок, чтоб регион стал таким:
    // ***
    // *  *
    // *   *
    // *    *
    // *    *
    // ******
    m_wnd_rgn_points[0].x = rc.left;
    m_wnd_rgn_points[0].y = rc.top;
    m_wnd_rgn_points[1].x = rc.right - 13;
    m_wnd_rgn_points[1].y = rc.top;
    m_wnd_rgn_points[2].x = rc.right;
    m_wnd_rgn_points[2].y = 14;
    m_wnd_rgn_points[3].x = rc.right;
    m_wnd_rgn_points[3].y = rc.bottom;
    m_wnd_rgn_points[4].x = rc.left;
    m_wnd_rgn_points[4].y = rc.bottom;
    m_wnd_rgn_points[5].x = rc.left;
    m_wnd_rgn_points[5].y = rc.top;
  }
}

HRESULT CControl::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
  m_rgn_bg = CreatePolygonRgn( m_wnd_rgn_points,sizeof(m_wnd_rgn_points)/sizeof(m_wnd_rgn_points[0]), ALTERNATE);

  int res = ::SetWindowRgn(m_hWnd,m_rgn_bg,true);

  return S_OK;
}

LRESULT CControl::OnEraseBkgnd(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
  HDC hDC = (HDC)wParam;
  DrawState(hDC, 0, 0, LPARAM(m_bmp_bg), 0, 0, 0, 0, 0, DST_BITMAP);

  return S_OK;
}


При этом битмап выводится целиком, и злополучный уголочек тоже.

Если делать и регион создавать в OnEraseBkgnd, то все работает, НО очень медленно. Мне нада спрятать 3 кнопки и все... нереальные тормоза, потому что после перерисовки каждой кнопки он создает регион и перерисовывает битмап. Убираешь оттуда создание региона — все круто, но не отсекает уголок.

Что же все таки я делаю не правильно???

Заранее спасибо.
Re: Задание региона для ActiveX.
От: AndrewJD США  
Дата: 01.10.04 13:55
Оценка:
Здравствуйте, buttercup, Вы писали:

B>Что-то у меня не получается задать регион для моего ActiveX контрола.


B>По WM_ERASEBACKGROUND рисую битмап... но правый вехний уголок битмапа мне нужно обрезать.



B>Если делать и регион создавать в OnEraseBkgnd, то все работает, НО очень медленно. Мне нада спрятать 3 кнопки и все... нереальные тормоза, потому что после перерисовки каждой кнопки он создает регион и перерисовывает битмап. Убираешь оттуда создание региона — все круто, но не отсекает уголок.


Вообще-то не очень круто юзать регионы в ActiveX — для этого есть режим windowless.
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Re[2]: Задание региона для ActiveX.
От: buttercup  
Дата: 01.10.04 14:25
Оценка:
Здравствуйте, AndrewJD, Вы писали:

AJD>Вообще-то не очень круто юзать регионы в ActiveX — для этого есть режим windowless.


Ну а что поделать если окошко мне все таки нужно... windowless насколько я понимаю подразумевает отсутствие такового???
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.