foobar2000 SDK  2015-01-14
misc.h
Go to the documentation of this file.
1 class CMenuSelectionReceiver : public CWindowImpl<CMenuSelectionReceiver> {
2 public:
3  CMenuSelectionReceiver(HWND p_parent) {
4  WIN32_OP( Create(p_parent) != NULL );
5  }
7  if (m_hWnd != NULL) DestroyWindow();
8  }
10  DECLARE_WND_CLASS_EX(TEXT("{DF0087DB-E765-4283-BBAB-6AB2E8AB64A1}"),0,0);
11 
13  MESSAGE_HANDLER(WM_MENUSELECT,OnMenuSelect)
15 protected:
16  virtual bool QueryHint(unsigned p_id,pfc::string_base & p_out) {
17  return false;
18  }
19 private:
20  LRESULT OnMenuSelect(UINT,WPARAM p_wp,LPARAM p_lp,BOOL&) {
21  if (p_lp != 0) {
22  if (HIWORD(p_wp) & MF_POPUP) {
23  m_status.release();
24  } else {
25  pfc::string8 msg;
26  if (!QueryHint(LOWORD(p_wp),msg)) {
27  m_status.release();
28  } else {
29  if (m_status.is_empty()) {
30  if (!static_api_ptr_t<ui_control>()->override_status_text_create(m_status)) m_status.release();
31  }
32  if (m_status.is_valid()) {
33  m_status->override_text(msg);
34  }
35  }
36  }
37  } else {
38  m_status.release();
39  }
40  return 0;
41  }
42 
44 
46 };
47 
49 public:
50  CMenuDescriptionMap(HWND p_parent) : CMenuSelectionReceiver(p_parent) {}
51  void Set(unsigned p_id,const char * p_description) {m_content.set(p_id,p_description);}
52 protected:
53  bool QueryHint(unsigned p_id,pfc::string_base & p_out) {
54  return m_content.query(p_id,p_out);
55  }
56 private:
58 };
59 
61 public:
63  void Set(unsigned id, const char * desc) {m_content.set(id, desc);}
64 
65  void SetCM(contextmenu_manager::ptr mgr, unsigned base, unsigned max) {
66  m_cmMgr = mgr; m_cmMgr_base = base; m_cmMgr_max = max;
67  }
68 protected:
69  bool QueryHint(unsigned p_id,pfc::string_base & p_out) {
70  if (m_cmMgr.is_valid() && p_id >= m_cmMgr_base && p_id < m_cmMgr_max) {
71  return m_cmMgr->get_description_by_id(p_id - m_cmMgr_base,p_out);
72  }
73  return m_content.query(p_id,p_out);
74  }
75 private:
77  contextmenu_manager::ptr m_cmMgr; unsigned m_cmMgr_base, m_cmMgr_max;
78 };
79 
80 inline pfc::string_base & operator<<(pfc::string_base & p_fmt,const CPoint & p_point) {
81  return p_fmt << "(" << p_point.x << "," << p_point.y << ")";
82 }
83 
84 inline pfc::string_base & operator<<(pfc::string_base & p_fmt,const CRect & p_rect) {
85  return p_fmt << "(" << p_rect.left << "," << p_rect.top << "," << p_rect.right << "," << p_rect.bottom << ")";
86 }
87 
88 template<typename TClass>
89 class CAddDummyMessageMap : public TClass {
90 public:
91  BEGIN_MSG_MAP(CAddDummyMessageMap<TClass>)
92  END_MSG_MAP()
93 };
94 
95 template<typename _parentClass> class CWindowFixSEH : public _parentClass { public:
96  BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID = 0) {
97  __try {
98  return _parentClass::ProcessWindowMessage(hWnd, uMsg, wParam, lParam, lResult, dwMsgMapID);
99  } __except(uExceptFilterProc(GetExceptionInformation())) { return FALSE; /* should not get here */ }
100  }
102 };
103 
104 template<typename TClass>
105 class CWindowAutoLifetime : public CWindowFixSEH<TClass> {
106 public:
108  CWindowAutoLifetime(HWND parent) : TBase() {Init(parent);}
109  template<typename TParam1> CWindowAutoLifetime(HWND parent, const TParam1 & p1) : TBase(p1) {Init(parent);}
110  template<typename TParam1,typename TParam2> CWindowAutoLifetime(HWND parent, const TParam1 & p1,const TParam2 & p2) : TBase(p1,p2) {Init(parent);}
111  template<typename TParam1,typename TParam2, typename TParam3> CWindowAutoLifetime(HWND parent, const TParam1 & p1,const TParam2 & p2,const TParam3 & p3) : TBase(p1,p2,p3) {Init(parent);}
112  template<typename TParam1,typename TParam2, typename TParam3, typename TParam4> CWindowAutoLifetime(HWND parent, const TParam1 & p1,const TParam2 & p2,const TParam3 & p3,const TParam4 & p4) : TBase(p1,p2,p3,p4) {Init(parent);}
113  template<typename TParam1,typename TParam2, typename TParam3, typename TParam4,typename TParam5> CWindowAutoLifetime(HWND parent, const TParam1 & p1,const TParam2 & p2,const TParam3 & p3,const TParam4 & p4, const TParam5 & p5) : TBase(p1,p2,p3,p4,p5) {Init(parent);}
114  template<typename TParam1,typename TParam2, typename TParam3, typename TParam4,typename TParam5,typename TParam6> CWindowAutoLifetime(HWND parent, const TParam1 & p1,const TParam2 & p2,const TParam3 & p3,const TParam4 & p4, const TParam5 & p5, const TParam6 & p6) : TBase(p1,p2,p3,p4,p5,p6) {Init(parent);}
115 private:
116  void Init(HWND parent) {WIN32_OP(this->Create(parent) != NULL);}
117  void OnFinalMessage(HWND wnd) {PFC_ASSERT_NO_EXCEPTION( TBase::OnFinalMessage(wnd) ); PFC_ASSERT_NO_EXCEPTION(delete this);}
118 };
119 
120 template<typename TClass>
121 class ImplementModelessTracking : public TClass {
122 public:
124 
126  MSG_WM_INITDIALOG(OnInitDialog)
127  MSG_WM_DESTROY(OnDestroy)
128  CHAIN_MSG_MAP(TClass)
129  END_MSG_MAP_HOOK()
130 private:
131  BOOL OnInitDialog(CWindow, LPARAM) {m_modeless.Set( m_hWnd ); SetMsgHandled(FALSE); return FALSE; }
132  void OnDestroy() {m_modeless.Set(NULL); SetMsgHandled(FALSE); }
134 };
135 
137 public:
138  CMenuSelectionReceiver_UiElement(service_ptr_t<ui_element_instance> p_owner,unsigned p_id_base) : CMenuSelectionReceiver(p_owner->get_wnd()), m_owner(p_owner), m_id_base(p_id_base) {}
139 protected:
140  bool QueryHint(unsigned p_id,pfc::string_base & p_out) {
141  return m_owner->edit_mode_context_menu_get_description(p_id,m_id_base,p_out);
142  }
143 private:
144  const unsigned m_id_base;
146 };
147 
149  CPoint pt;
150  bool fromKeyboard;
151  if (p_pt == -1) {
152  fromKeyboard = true;
153  if (!p_elem->edit_mode_context_menu_get_focus_point(pt)) {
154  CRect rc;
155  WIN32_OP_D( GetWindowRect(p_elem->get_wnd(), rc) );
156  pt = rc.CenterPoint();
157  }
158  } else {
159  fromKeyboard = false;
160  pt = p_pt;
161  }
162  if (p_elem->edit_mode_context_menu_test(pt,fromKeyboard)) {
163  const unsigned idBase = 1;
164  CMenu menu;
165  WIN32_OP( menu.CreatePopupMenu() );
166  p_elem->edit_mode_context_menu_build(pt,fromKeyboard,menu,idBase);
167 
168  int cmd;
169  {
170  CMenuSelectionReceiver_UiElement receiver(p_elem,idBase);
171  cmd = menu.TrackPopupMenu(TPM_RIGHTBUTTON|TPM_NONOTIFY|TPM_RETURNCMD,pt.x,pt.y,receiver);
172  }
173  if (cmd > 0) p_elem->edit_mode_context_menu_command(pt,fromKeyboard,cmd,idBase);
174  }
175 }
177  try {
179  } catch(std::exception const & e) {
180  console::complain("Context menu failure", e);
181  }
182 }
183 
184 
185 #if _WIN32_WINNT >= 0x501
186 static void HeaderControl_SetSortIndicator(CHeaderCtrl header, int column, bool isUp) {
187  const int total = header.GetItemCount();
188  for(int walk = 0; walk < total; ++walk) {
189  HDITEM item = {}; item.mask = HDI_FORMAT;
190  if (header.GetItem(walk,&item)) {
191  DWORD newFormat = item.fmt;
192  newFormat &= ~( HDF_SORTUP | HDF_SORTDOWN );
193  if (walk == column) {
194  newFormat |= isUp ? HDF_SORTUP : HDF_SORTDOWN;
195  }
196  if (newFormat != item.fmt) {
197  item.fmt = newFormat;
198  header.SetItem(walk,&item);
199  }
200  }
201  }
202 }
203 #endif
204 
205 typedef CWinTraits<WS_POPUP,WS_EX_TRANSPARENT|WS_EX_LAYERED|WS_EX_TOPMOST|WS_EX_TOOLWINDOW> CFlashWindowTraits;
206 
207 class CFlashWindow : public CWindowImpl<CFlashWindow,CWindow,CFlashWindowTraits> {
208 public:
209  void Activate(CWindow parent) {
210  ShowAbove(parent);
211  m_tickCount = 0;
212  SetTimer(KTimerID, 500);
213  }
214  void Deactivate() throw() {
215  ShowWindow(SW_HIDE); KillTimer(KTimerID);
216  }
217 
218  void ShowAbove(CWindow parent) {
219  if (m_hWnd == NULL) {
220  WIN32_OP( Create(NULL) != NULL );
221  }
222  CRect rect;
223  WIN32_OP_D( parent.GetWindowRect(rect) );
224  WIN32_OP_D( SetWindowPos(NULL,rect,SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW) );
225  m_parent = parent;
226  }
227 
228  void CleanUp() throw() {
229  if (m_hWnd != NULL) DestroyWindow();
230  }
231 
233  MSG_WM_CREATE(OnCreate)
234  MSG_WM_TIMER(OnTimer)
235  MSG_WM_DESTROY(OnDestroy)
236  END_MSG_MAP()
237 
238  DECLARE_WND_CLASS_EX(TEXT("{2E124D52-131F-4004-A569-2316615BE63F}"),0,COLOR_HIGHLIGHT);
239 private:
240  void OnDestroy() throw() {
241  KillTimer(KTimerID);
242  }
243  enum {
244  KTimerID = 0x47f42dd0
245  };
246  void OnTimer(WPARAM id) {
247  if (id == KTimerID) {
248  switch(++m_tickCount) {
249  case 1:
250  ShowWindow(SW_HIDE);
251  break;
252  case 2:
253  ShowAbove(m_parent);
254  break;
255  case 3:
256  ShowWindow(SW_HIDE);
257  KillTimer(KTimerID);
258  break;
259  }
260  }
261  }
262  LRESULT OnCreate(LPCREATESTRUCT) throw() {
263  SetLayeredWindowAttributes(*this,0,128,LWA_ALPHA);
264  return 0;
265  }
266  CWindow m_parent;
267  t_uint32 m_tickCount;
268 };
269 
270 class CTypableWindowScope {
271 public:
272  CTypableWindowScope() : m_wnd() {}
273  ~CTypableWindowScope() {Set(NULL);}
274  void Set(HWND wnd) {
275  try {
276  if (m_wnd != NULL) {
277  static_api_ptr_t<ui_element_typable_window_manager>()->remove(m_wnd);
278  }
279  m_wnd = wnd;
280  if (m_wnd != NULL) {
281  static_api_ptr_t<ui_element_typable_window_manager>()->add(m_wnd);
282  }
283  } catch(exception_service_not_found) {
284  m_wnd = NULL;
285  }
286  }
287 
288 private:
289  HWND m_wnd;
290  PFC_CLASS_NOT_COPYABLE_EX(CTypableWindowScope);
291 };
292 
293 
294 template<typename TBase> class CContainedWindowSimpleT : public CContainedWindowT<TBase>, public CMessageMap {
295 public:
296  CContainedWindowSimpleT() : CContainedWindowT<TBase>(this) {}
297  BEGIN_MSG_MAP(CContainedWindowSimpleT)
298  END_MSG_MAP()
299 };
300 
301 
302 static bool window_service_trait_defer_destruction(const service_base *) {return true;}
303 
304 
306 template<typename _t_base>
307 class window_service_impl_t : public CWindowFixSEH<_t_base> {
308 private:
309  typedef window_service_impl_t<_t_base> t_self;
310  typedef CWindowFixSEH<_t_base> t_base;
311 public:
312  BEGIN_MSG_MAP_EX(window_service_impl_t)
313  MSG_WM_DESTROY(OnDestroyPassThru)
314  CHAIN_MSG_MAP(__super)
315  END_MSG_MAP_HOOK()
316 
317  int FB2KAPI service_release() throw() {
318  int ret = --m_counter;
319  if (ret == 0) {
320  if (window_service_trait_defer_destruction(this) && !InterlockedExchange(&m_delayedDestroyInProgress,1)) {
321  PFC_ASSERT_NO_EXCEPTION( service_impl_helper::release_object_delayed(this); );
322  } else if (m_hWnd != NULL) {
323  if (!m_destroyWindowInProgress) { // don't double-destroy in weird scenarios
324  PFC_ASSERT_NO_EXCEPTION( ::DestroyWindow(m_hWnd) );
325  }
326  } else {
327  PFC_ASSERT_NO_EXCEPTION( delete this );
328  }
329  }
330  return ret;
331  }
332  int FB2KAPI service_add_ref() throw() {return ++m_counter;}
333 
334  TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD_WITH_INITIALIZER(window_service_impl_t,t_base,{m_destroyWindowInProgress = false; m_delayedDestroyInProgress = 0; })
335 private:
336  void OnDestroyPassThru() {
337  SetMsgHandled(FALSE); m_destroyWindowInProgress = true;
338  }
339  void OnFinalMessage(HWND p_wnd) {
340  t_base::OnFinalMessage(p_wnd);
341  service_ptr_t<service_base> bump(this);
342  }
343  volatile bool m_destroyWindowInProgress;
344  volatile LONG m_delayedDestroyInProgress;
345  pfc::refcounter m_counter;
346 };
347 
348 
349 static void AppendMenuPopup(HMENU menu, UINT flags, CMenu & popup, const TCHAR * label) {
350  PFC_ASSERT( flags & MF_POPUP );
351  WIN32_OP( CMenuHandle(menu).AppendMenu(flags, popup, label) );
352  popup.Detach();
353 }
354 
355 class CMessageMapDummy : public CMessageMap {
356 public:
357  BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
358  LRESULT& lResult, DWORD dwMsgMapID) {return FALSE;}
359 };
360 
361 class CPopupTooltipMessage {
362 public:
363  CPopupTooltipMessage(DWORD style = TTS_BALLOON | TTS_NOPREFIX) : m_style(style | WS_POPUP), m_toolinfo(), m_shutDown() {}
364  void ShowFocus(const TCHAR * message, CWindow wndParent) {
365  Show(message, wndParent); wndParent.SetFocus();
366  }
367  void Show(const TCHAR * message, CWindow wndParent) {
368  if (m_shutDown || (message == NULL && m_tooltip.m_hWnd == NULL)) return;
369  Initialize();
370  Hide();
371 
372  if (message != NULL) {
373  CRect rect;
374  WIN32_OP_D( wndParent.GetWindowRect(rect) );
375  ShowInternal(message, wndParent, rect);
376  }
377  }
378  void ShowEx(const TCHAR * message, CWindow wndParent, CRect rect) {
379  if (m_shutDown) return;
380  Initialize();
381  Hide();
382  ShowInternal(message, wndParent, rect);
383  }
384  void Hide() {
385  if (m_tooltip.m_hWnd != NULL && m_tooltip.GetToolCount() > 0) {
386  m_tooltip.TrackActivate(&m_toolinfo,FALSE);
387  m_tooltip.DelTool(&m_toolinfo);
388  }
389  }
390 
391  void CleanUp() {
392  if (m_tooltip.m_hWnd != NULL) {
393  m_tooltip.DestroyWindow();
394  }
395  }
396  void ShutDown() {
397  m_shutDown = true; CleanUp();
398  }
399 private:
400  void ShowInternal(const TCHAR * message, CWindow wndParent, CRect rect) {
401  PFC_ASSERT( !m_shutDown );
402  PFC_ASSERT( message != NULL );
403  PFC_ASSERT( wndParent != NULL );
404  m_toolinfo.cbSize = sizeof(m_toolinfo);
405  m_toolinfo.uFlags = TTF_TRACK|TTF_IDISHWND|TTF_ABSOLUTE|TTF_TRANSPARENT|TTF_CENTERTIP;
406  m_toolinfo.hwnd = wndParent;
407  m_toolinfo.uId = 0;
408  m_toolinfo.lpszText = const_cast<TCHAR*>(message);
409  m_toolinfo.hinst = NULL; //core_api::get_my_instance();
410  if (m_tooltip.AddTool(&m_toolinfo)) {
411  m_tooltip.TrackPosition(rect.CenterPoint().x,rect.bottom);
412  m_tooltip.TrackActivate(&m_toolinfo,TRUE);
413  }
414  }
415  void Initialize() {
416  if (m_tooltip.m_hWnd == NULL) {
417  WIN32_OP( m_tooltip.Create( NULL , NULL, NULL, m_style) );
418  }
419  }
420  CContainedWindowSimpleT<CToolTipCtrl> m_tooltip;
421  TOOLINFO m_toolinfo;
422  const DWORD m_style;
423  bool m_shutDown;
424 };
425 
426 
427 template<typename T> class CDialogWithTooltip : public CDialogImpl<T> {
428 public:
429  BEGIN_MSG_MAP(CDialogWithTooltip)
430  MSG_WM_DESTROY(OnDestroy)
431  END_MSG_MAP()
432 
433  void ShowTip(UINT id, const TCHAR * label) {
434  m_tip.Show(label, GetDlgItem(id));
435  }
436  void ShowTip(HWND child, const TCHAR * label) {
437  m_tip.Show(label, child);
438  }
439 
440  void ShowTipF(UINT id, const TCHAR * label) {
441  m_tip.ShowFocus(label, GetDlgItem(id));
442  }
443  void ShowTipF(HWND child, const TCHAR * label) {
444  m_tip.ShowFocus(label, child);
445  }
446  void HideTip() {m_tip.Hide();}
447 private:
448  void OnDestroy() {m_tip.ShutDown(); SetMsgHandled(FALSE); }
449  CPopupTooltipMessage m_tip;
450 };
451 
452 
453 
454 
455 
456 
457 
458 
459 static void ListView_FixContextMenuPoint(CListViewCtrl list,CPoint & coords) {
460  if (coords == CPoint(-1,-1)) {
461  int selWalk = -1;
462  CRect rcClient; WIN32_OP_D(list.GetClientRect(rcClient));
463  for(;;) {
464  selWalk = list.GetNextItem(selWalk, LVNI_SELECTED);
465  if (selWalk < 0) {
466  CRect rc;
467  WIN32_OP_D( list.GetWindowRect(&rc) );
468  coords = rc.CenterPoint();
469  return;
470  }
471  CRect rcItem, rcVisible;
472  WIN32_OP_D( list.GetItemRect(selWalk, &rcItem, LVIR_BOUNDS) );
473  if (rcVisible.IntersectRect(rcItem, rcClient)) {
474  coords = rcVisible.CenterPoint();
475  WIN32_OP_D( list.ClientToScreen(&coords) );
476  return;
477  }
478  }
479  }
480 }
481 
482 
483 template<typename TDialog> class preferences_page_instance_impl : public TDialog {
484 public:
485  preferences_page_instance_impl(HWND parent, preferences_page_callback::ptr callback) : TDialog(callback) {WIN32_OP(this->Create(parent) != NULL);}
486  HWND get_wnd() {return this->m_hWnd;}
487 };
488 static bool window_service_trait_defer_destruction(const preferences_page_instance *) {return false;}
489 template<typename TDialog> class preferences_page_impl : public preferences_page_v3 {
490 public:
491  preferences_page_instance::ptr instantiate(HWND parent, preferences_page_callback::ptr callback) {
492  return new window_service_impl_t<preferences_page_instance_impl<TDialog> >(parent, callback);
493  }
494 };
495 
496 class CEmbeddedDialog : public CDialogImpl<CEmbeddedDialog> {
497 public:
498  CEmbeddedDialog(CMessageMap * owner, DWORD msgMapID, UINT dialogID) : m_owner(*owner), IDD(dialogID), m_msgMapID(msgMapID) {}
499 
500  BEGIN_MSG_MAP(CEmbeddedDialog)
501  CHAIN_MSG_MAP_ALT_MEMBER(m_owner, m_msgMapID)
502  END_MSG_MAP()
503 
504  const DWORD m_msgMapID;
505  const UINT IDD;
506  CMessageMap & m_owner;
507 };
508 
509 
510 void PaintSeparatorControl(CWindow wnd);
511 
512 class CStaticSeparator : public CContainedWindowT<CStatic>, private CMessageMap {
513 public:
514  CStaticSeparator() : CContainedWindowT<CStatic>(this, 0) {}
515  BEGIN_MSG_MAP_EX(CSeparator)
516  MSG_WM_PAINT(OnPaint)
517  MSG_WM_SETTEXT(OnSetText)
518  END_MSG_MAP()
519 private:
520  int OnSetText(LPCTSTR lpstrText) {
521  Invalidate();
522  SetMsgHandled(FALSE);
523  return 0;
524  }
525  void OnPaint(CDCHandle) {
526  PaintSeparatorControl(*this);
527  }
528 };
529 
530 
531 
532 template<typename TClass>
533 class CTextControl : public CWindowRegisteredT<TClass> {
534 public:
535  BEGIN_MSG_MAP_EX(CTextControl)
536  MSG_WM_SETFONT(OnSetFont)
537  MSG_WM_GETFONT(OnGetFont)
538  MSG_WM_SETTEXT(OnSetText)
539  CHAIN_MSG_MAP(__super)
540  END_MSG_MAP()
541 private:
542  HFONT OnGetFont() {
543  return m_font;
544  }
545  void OnSetFont(HFONT font, BOOL bRedraw) {
546  m_font = font;
547  if (bRedraw) Invalidate();
548  }
549  int OnSetText(LPCTSTR lpstrText) {
550  Invalidate();SetMsgHandled(FALSE); return 0;
551  }
552  CFontHandle m_font;
553 };
554 
555 #ifndef VSCLASS_TEXTSTYLE
556 //
557 // TEXTSTYLE class parts and states
558 //
559 #define VSCLASS_TEXTSTYLE L"TEXTSTYLE"
560 
561 enum TEXTSTYLEPARTS {
562  TEXT_MAININSTRUCTION = 1,
563  TEXT_INSTRUCTION = 2,
564  TEXT_BODYTITLE = 3,
565  TEXT_BODYTEXT = 4,
566  TEXT_SECONDARYTEXT = 5,
567  TEXT_HYPERLINKTEXT = 6,
568  TEXT_EXPANDED = 7,
569  TEXT_LABEL = 8,
570  TEXT_CONTROLLABEL = 9,
571 };
572 
573 enum HYPERLINKTEXTSTATES {
574  TS_HYPERLINK_NORMAL = 1,
575  TS_HYPERLINK_HOT = 2,
576  TS_HYPERLINK_PRESSED = 3,
577  TS_HYPERLINK_DISABLED = 4,
578 };
579 
580 enum CONTROLLABELSTATES {
581  TS_CONTROLLABEL_NORMAL = 1,
582  TS_CONTROLLABEL_DISABLED = 2,
583 };
584 
585 #endif
586 
587 
588 class CStaticThemed : public CContainedWindowT<CStatic>, private CMessageMap {
589 public:
590  CStaticThemed() : CContainedWindowT<CStatic>(this, 0), m_id(), m_fallback() {}
591  BEGIN_MSG_MAP_EX(CStaticThemed)
592  MSG_WM_PAINT(OnPaint)
593  MSG_WM_THEMECHANGED(OnThemeChanged)
594  MSG_WM_SETTEXT(OnSetText)
595  END_MSG_MAP()
596 
597  void SetThemePart(int id) {m_id = id; if (m_hWnd != NULL) Invalidate();}
598 private:
599  int OnSetText(LPCTSTR lpstrText) {
600  Invalidate();
601  SetMsgHandled(FALSE);
602  return 0;
603  }
604  void OnThemeChanged() {
605  m_theme.Release();
606  m_fallback = false;
607  }
608  void OnPaint(CDCHandle) {
609  if (m_fallback) {
610  SetMsgHandled(FALSE); return;
611  }
612  if (m_theme == NULL) {
613  m_theme.OpenThemeData(*this, L"TextStyle");
614  if (m_theme == NULL) {
615  m_fallback = true; SetMsgHandled(FALSE); return;
616  }
617  }
618  CPaintDC dc(*this);
619  TCHAR buffer[512] = {};
620  GetWindowText(buffer, _countof(buffer));
621  const int txLen = pfc::strlen_max_t(buffer, _countof(buffer));
622  CRect contentRect;
623  WIN32_OP_D( GetClientRect(contentRect) );
624  SelectObjectScope scopeFont(dc, GetFont());
625  dc.SetTextColor(GetSysColor(COLOR_WINDOWTEXT));
626  dc.SetBkMode(TRANSPARENT);
627 
628  if (txLen > 0) {
629  CRect rcText(contentRect);
630  DWORD flags = 0;
631  DWORD style = GetStyle();
632  if (style & SS_LEFT) flags |= DT_LEFT;
633  else if (style & SS_RIGHT) flags |= DT_RIGHT;
634  else if (style & SS_CENTER) flags |= DT_CENTER;
635  if (style & SS_ENDELLIPSIS) flags |= DT_END_ELLIPSIS;
636 
637  HRESULT retval = DrawThemeText(m_theme, dc, m_id, 0, buffer, txLen, flags, 0, rcText);
638  PFC_ASSERT( SUCCEEDED( retval ) );
639  }
640  }
641  int m_id;
642  CTheme m_theme;
643  bool m_fallback;
644 };
645 class CStaticMainInstruction : public CStaticThemed {
646 public:
647  CStaticMainInstruction() { SetThemePart(TEXT_MAININSTRUCTION); }
648 };
649 
650 
651 
652 class CSeparator : public CTextControl<CSeparator> {
653 public:
654  BEGIN_MSG_MAP_EX(CSeparator)
655  MSG_WM_PAINT(OnPaint)
656  CHAIN_MSG_MAP(__super)
657  END_MSG_MAP()
658 
659  static const TCHAR * GetClassName() {
660  return _T("foobar2000:separator");
661  }
662 private:
663  void OnPaint(CDCHandle dc) {
664  PaintSeparatorControl(*this);
665  }
666 };
667 
pfc::string_base & operator<<(pfc::string_base &p_fmt, const CPoint &p_point)
Definition: misc.h:80
BEGIN_MSG_MAP_EX(CFlashWindow) MSG_WM_CREATE(OnCreate) MSG_WM_TIMER(OnTimer) MSG_WM_DESTROY(OnDestroy) END_MSG_MAP() DECLARE_WND_CLASS_EX(TEXT("
Definition: misc.h:232
CWindowAutoLifetime(HWND parent)
Definition: misc.h:108
CWindowAutoLifetime(HWND parent, const TParam1 &p1, const TParam2 &p2, const TParam3 &p3, const TParam4 &p4, const TParam5 &p5)
Definition: misc.h:113
void Init(HWND parent)
Definition: misc.h:116
CWindow m_parent
Definition: misc.h:266
LONG SHARED_EXPORT uExceptFilterProc(LPEXCEPTION_POINTERS param)
bool is_empty() const
Definition: service.h:120
void OnDestroy()
Definition: misc.h:240
void ShowAbove(CWindow parent)
Definition: misc.h:218
typedef BOOL(WINAPI *pPowerSetRequest_t)(__in HANDLE PowerRequest
BEGIN_MSG_MAP_EX(ImplementModelessTracking) MSG_WM_INITDIALOG(OnInitDialog) MSG_WM_DESTROY(OnDestroy) CHAIN_MSG_MAP(TClass) END_MSG_MAP_HOOK() private
Definition: misc.h:125
PFC_CLASS_NOT_COPYABLE(CMenuSelectionReceiver, CMenuSelectionReceiver)
void OnFinalMessage(HWND wnd)
Definition: misc.h:117
static void HeaderControl_SetSortIndicator(CHeaderCtrl header, int column, bool isUp)
Definition: misc.h:186
unsigned m_cmMgr_max
Definition: misc.h:77
void Deactivate()
Definition: misc.h:214
pfc::map_t< unsigned, pfc::string8 > m_content
Definition: misc.h:57
TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD(ImplementModelessTracking, TClass)
BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT &lResult, DWORD dwMsgMapID=0)
Definition: misc.h:96
bool QueryHint(unsigned p_id, pfc::string_base &p_out)
Definition: misc.h:53
void OnTimer(WPARAM id)
Definition: misc.h:246
LRESULT OnMenuSelect(UINT, WPARAM p_wp, LPARAM p_lp, BOOL &)
Definition: misc.h:20
CWinTraits< WS_POPUP, WS_EX_TRANSPARENT|WS_EX_LAYERED|WS_EX_TOPMOST|WS_EX_TOOLWINDOW > CFlashWindowTraits
Definition: misc.h:205
void complain(const char *what, const char *msg)
Definition: console.cpp:21
CMenuDescriptionMap(HWND p_parent)
Definition: misc.h:50
CModelessDialogEntry m_modeless
Definition: misc.h:133
pfc::map_t< unsigned, pfc::string8 > m_content
Definition: misc.h:76
bool is_valid() const
Definition: service.h:119
CWindowAutoLifetime(HWND parent, const TParam1 &p1, const TParam2 &p2, const TParam3 &p3)
Definition: misc.h:111
void Set(unsigned id, const char *desc)
Definition: misc.h:63
t_uint32 m_tickCount
Definition: misc.h:267
~CMenuSelectionReceiver()
Definition: misc.h:6
const unsigned m_id_base
Definition: misc.h:144
void release()
Definition: service.h:109
void Set(HWND p_new)
Definition: win32_misc.h:191
void CleanUp()
Definition: misc.h:228
OnMenuSelect END_MSG_MAP() protected
Definition: misc.h:14
void Set(unsigned p_id, const char *p_description)
Definition: misc.h:51
BEGIN_MSG_MAP(CMenuSelectionReceiver) MESSAGE_HANDLER(WM_MENUSELECT
CWindowAutoLifetime(HWND parent, const TParam1 &p1)
Definition: misc.h:109
LRESULT OnCreate(LPCREATESTRUCT)
Definition: misc.h:262
TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD(CWindowFixSEH, _parentClass)
void set(const _t_key &p_key, const _t_value &p_value)
Definition: map.h:22
CMenuSelectionReceiver_UiElement(service_ptr_t< ui_element_instance > p_owner, unsigned p_id_base)
Definition: misc.h:138
unsigned m_cmMgr_base
Definition: misc.h:77
std::exception exception
Definition: primitives.h:193
CWindowAutoLifetime(HWND parent, const TParam1 &p1, const TParam2 &p2)
Definition: misc.h:110
contextmenu_manager::ptr m_cmMgr
Definition: misc.h:77
void SetCM(contextmenu_manager::ptr mgr, unsigned base, unsigned max)
Definition: misc.h:65
CWindowFixSEH< TClass > TBase
Definition: misc.h:107
service_ptr_t< ui_status_text_override > m_status
Definition: misc.h:43
static void ui_element_instance_standard_context_menu_eh(service_ptr_t< ui_element_instance > p_elem, LPARAM p_pt)
Definition: misc.h:176
const service_ptr_t< ui_element_instance > m_owner
Definition: misc.h:145
static void ui_element_instance_standard_context_menu(service_ptr_t< ui_element_instance > p_elem, LPARAM p_pt)
Definition: misc.h:148
DECLARE_WND_CLASS_EX(TEXT("{DF0087DB-E765-4283-BBAB-6AB2E8AB64A1}"), 0, 0)
Helper template used to easily access core services. Usage: static_api_ptr_t api; api->doso...
Definition: service.h:533
CMenuSelectionReceiver(HWND p_parent)
Definition: misc.h:3
CWindowAutoLifetime(HWND parent, const TParam1 &p1, const TParam2 &p2, const TParam3 &p3, const TParam4 &p4, const TParam5 &p5, const TParam6 &p6)
Definition: misc.h:114
CMenuDescriptionHybrid(HWND parent)
Definition: misc.h:62
CWindowImpl< CMenuSelectionReceiver > _baseClass
Definition: misc.h:9
bool QueryHint(unsigned p_id, pfc::string_base &p_out)
Definition: misc.h:69
void Activate(CWindow parent)
Definition: misc.h:209
CWindowAutoLifetime(HWND parent, const TParam1 &p1, const TParam2 &p2, const TParam3 &p3, const TParam4 &p4)
Definition: misc.h:112
bool QueryHint(unsigned p_id, pfc::string_base &p_out)
Definition: misc.h:140
bool query(const _t_key &p_key, _t_value &p_value) const
Definition: map.h:44