home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / VDLib / source / UIProxies.cpp < prev   
Encoding:
C/C++ Source or Header  |  2009-09-14  |  10.7 KB  |  430 lines

  1. #include "stdafx.h"
  2. #include <windows.h>
  3. #include <commctrl.h>
  4.  
  5. #include <vd2/system/w32assist.h>
  6. #include <vd2/Dita/accel.h>
  7. #include <vd2/VDLib/UIProxies.h>
  8.  
  9. ///////////////////////////////////////////////////////////////////////////////
  10.  
  11. VDUIProxyControl::VDUIProxyControl()
  12.     : mhwnd(NULL)
  13. {
  14. }
  15.  
  16. void VDUIProxyControl::Attach(VDZHWND hwnd) {
  17.     VDASSERT(IsWindow(hwnd));
  18.     mhwnd = hwnd;
  19. }
  20.  
  21. void VDUIProxyControl::Detach() {
  22.     mhwnd = NULL;
  23. }
  24.  
  25. VDZLRESULT VDUIProxyControl::On_WM_NOTIFY(VDZWPARAM wParam, VDZLPARAM lParam) {
  26.     return 0;
  27. }
  28.  
  29. VDZLRESULT VDUIProxyControl::On_WM_COMMAND(VDZWPARAM wParam, VDZLPARAM lParam) {
  30.     return 0;
  31. }
  32.  
  33. ///////////////////////////////////////////////////////////////////////////////
  34.  
  35. void VDUIProxyMessageDispatcherW32::AddControl(VDUIProxyControl *control) {
  36.     VDZHWND hwnd = control->GetHandle();
  37.     size_t hc = Hash(hwnd);
  38.  
  39.     mHashTable[hc].push_back(control);
  40. }
  41.  
  42. void VDUIProxyMessageDispatcherW32::RemoveControl(VDZHWND hwnd) {
  43.     size_t hc = Hash(hwnd);
  44.     HashChain& hchain = mHashTable[hc];
  45.  
  46.     HashChain::iterator it(hchain.begin()), itEnd(hchain.end());
  47.     for(; it != itEnd; ++it) {
  48.         VDUIProxyControl *control = *it;
  49.  
  50.         if (control->GetHandle() == hwnd) {
  51.             hchain.erase(control);
  52.             break;
  53.         }
  54.     }
  55.  
  56. }
  57.  
  58. void VDUIProxyMessageDispatcherW32::RemoveAllControls() {
  59.     for(int i=0; i<kHashTableSize; ++i)
  60.         mHashTable[i].clear();
  61. }
  62.  
  63. VDZLRESULT VDUIProxyMessageDispatcherW32::Dispatch_WM_COMMAND(VDZWPARAM wParam, VDZLPARAM lParam) {
  64.     VDUIProxyControl *control = GetControl((HWND)lParam);
  65.  
  66.     if (control)
  67.         return control->On_WM_COMMAND(wParam, lParam);
  68.  
  69.     return 0;
  70. }
  71.  
  72. VDZLRESULT VDUIProxyMessageDispatcherW32::Dispatch_WM_NOTIFY(VDZWPARAM wParam, VDZLPARAM lParam) {
  73.     const NMHDR *hdr = (const NMHDR *)lParam;
  74.     VDUIProxyControl *control = GetControl(hdr->hwndFrom);
  75.  
  76.     if (control)
  77.         return control->On_WM_NOTIFY(wParam, lParam);
  78.  
  79.     return 0;
  80. }
  81.  
  82. size_t VDUIProxyMessageDispatcherW32::Hash(VDZHWND hwnd) const {
  83.     return (size_t)hwnd % (size_t)kHashTableSize;
  84. }
  85.  
  86. VDUIProxyControl *VDUIProxyMessageDispatcherW32::GetControl(VDZHWND hwnd) {
  87.     size_t hc = Hash(hwnd);
  88.     HashChain& hchain = mHashTable[hc];
  89.  
  90.     HashChain::iterator it(hchain.begin()), itEnd(hchain.end());
  91.     for(; it != itEnd; ++it) {
  92.         VDUIProxyControl *control = *it;
  93.  
  94.         if (control->GetHandle() == hwnd)
  95.             return control;
  96.     }
  97.  
  98.     return NULL;
  99. }
  100.  
  101. ///////////////////////////////////////////////////////////////////////////////
  102.  
  103. ///////////////////////////////////////////////////////////////////////////////
  104.  
  105. VDUIProxyListView::VDUIProxyListView()
  106.     : mNextTextIndex(0)
  107. {
  108. }
  109.  
  110. void VDUIProxyListView::AutoSizeColumns() {
  111.     const int colCount = GetColumnCount();
  112.  
  113.     for(int col=0; col<colCount; ++col) {
  114.         SendMessage(mhwnd, LVM_SETCOLUMNWIDTH, col, LVSCW_AUTOSIZE_USEHEADER);
  115.         const int hdrWidth = SendMessage(mhwnd, LVM_GETCOLUMNWIDTH, col, 0);
  116.  
  117.         SendMessage(mhwnd, LVM_SETCOLUMNWIDTH, col, LVSCW_AUTOSIZE);
  118.         const int dataWidth = SendMessage(mhwnd, LVM_GETCOLUMNWIDTH, col, 0);
  119.  
  120.         if (dataWidth < hdrWidth)
  121.             SendMessage(mhwnd, LVM_SETCOLUMNWIDTH, col, hdrWidth);
  122.     }
  123. }
  124.  
  125. void VDUIProxyListView::Clear() {
  126.     if (mhwnd)
  127.         SendMessage(mhwnd, LVM_DELETEALLITEMS, 0, 0);
  128. }
  129.  
  130. void VDUIProxyListView::DeleteItem(int index) {
  131.     SendMessage(mhwnd, LVM_DELETEITEM, index, 0);
  132. }
  133.  
  134. int VDUIProxyListView::GetColumnCount() const {
  135.     HWND hwndHeader = (HWND)SendMessage(mhwnd, LVM_GETHEADER, 0, 0);
  136.     if (!hwndHeader)
  137.         return 0;
  138.  
  139.     return (int)SendMessage(hwndHeader, HDM_GETITEMCOUNT, 0, 0);
  140. }
  141.  
  142. int VDUIProxyListView::GetItemCount() const {
  143.     return (int)SendMessage(mhwnd, LVM_GETITEMCOUNT, 0, 0);
  144. }
  145.  
  146. int VDUIProxyListView::GetSelectedIndex() const {
  147.     return ListView_GetNextItem(mhwnd, -1, LVNI_SELECTED);
  148. }
  149.  
  150. void VDUIProxyListView::SetSelectedIndex(int index) {
  151.     ListView_SetItemState(mhwnd, index, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED);
  152. }
  153.  
  154. void VDUIProxyListView::SetFullRowSelectEnabled(bool enabled) {
  155.     ListView_SetExtendedListViewStyleEx(mhwnd, LVS_EX_FULLROWSELECT, enabled ? LVS_EX_FULLROWSELECT : 0);
  156. }
  157.  
  158. void VDUIProxyListView::EnsureItemVisible(int index) {
  159.     ListView_EnsureVisible(mhwnd, index, FALSE);
  160. }
  161.  
  162. int VDUIProxyListView::GetVisibleTopIndex() {
  163.     return ListView_GetTopIndex(mhwnd);
  164. }
  165.  
  166. void VDUIProxyListView::SetVisibleTopIndex(int index) {
  167.     int n = ListView_GetItemCount(mhwnd);
  168.     if (n > 0) {
  169.         ListView_EnsureVisible(mhwnd, n - 1, FALSE);
  170.         ListView_EnsureVisible(mhwnd, index, FALSE);
  171.     }
  172. }
  173.  
  174. IVDUIListViewVirtualItem *VDUIProxyListView::GetVirtualItem(int index) const {
  175.     if (index < 0)
  176.         return NULL;
  177.  
  178.     if (VDIsWindowsNT()) {
  179.         LVITEMW itemw={};
  180.         itemw.mask = LVIF_PARAM;
  181.         itemw.iItem = index;
  182.         itemw.iSubItem = 0;
  183.         if (SendMessage(mhwnd, LVM_GETITEMA, 0, (LPARAM)&itemw))
  184.             return (IVDUIListViewVirtualItem *)itemw.lParam;
  185.     } else {
  186.         LVITEMA itema={};
  187.         itema.mask = LVIF_PARAM;
  188.         itema.iItem = index;
  189.         itema.iSubItem = 0;
  190.         if (SendMessage(mhwnd, LVM_GETITEMW, 0, (LPARAM)&itema))
  191.             return (IVDUIListViewVirtualItem *)itema.lParam;
  192.     }
  193.  
  194.     return NULL;
  195. }
  196.  
  197. void VDUIProxyListView::InsertColumn(int index, const wchar_t *label, int width) {
  198.     if (VDIsWindowsNT()) {
  199.         LVCOLUMNW colw = {};
  200.  
  201.         colw.mask        = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
  202.         colw.fmt        = LVCFMT_LEFT;
  203.         colw.cx            = width;
  204.         colw.pszText    = (LPWSTR)label;
  205.  
  206.         SendMessageW(mhwnd, LVM_INSERTCOLUMNW, (WPARAM)index, (LPARAM)&colw);
  207.     } else {
  208.         LVCOLUMNA cola = {};
  209.         VDStringA labela(VDTextWToA(label));
  210.  
  211.         cola.mask        = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
  212.         cola.fmt        = LVCFMT_LEFT;
  213.         cola.cx            = width;
  214.         cola.pszText    = (LPSTR)labela.c_str();
  215.  
  216.         SendMessageA(mhwnd, LVM_INSERTCOLUMNA, (WPARAM)index, (LPARAM)&cola);
  217.     }
  218. }
  219.  
  220. int VDUIProxyListView::InsertItem(int item, const wchar_t *text) {
  221.     if (item < 0)
  222.         item = 0x7FFFFFFF;
  223.  
  224.     if (VDIsWindowsNT()) {
  225.         LVITEMW itemw = {};
  226.  
  227.         itemw.mask        = LVIF_TEXT;
  228.         itemw.iItem        = item;
  229.         itemw.pszText    = (LPWSTR)text;
  230.  
  231.         return (int)SendMessageW(mhwnd, LVM_INSERTITEMW, 0, (LPARAM)&itemw);
  232.     } else {
  233.         LVITEMA itema = {};
  234.         VDStringA texta(VDTextWToA(text));
  235.  
  236.         itema.mask        = LVIF_TEXT;
  237.         itema.iItem        = item;
  238.         itema.pszText    = (LPSTR)texta.c_str();
  239.  
  240.         return (int)SendMessageA(mhwnd, LVM_INSERTITEMA, 0, (LPARAM)&itema);
  241.     }
  242. }
  243.  
  244. int VDUIProxyListView::InsertVirtualItem(int item, IVDUIListViewVirtualItem *lvvi) {
  245.     int index;
  246.  
  247.     if (item < 0)
  248.         item = 0x7FFFFFFF;
  249.  
  250.     if (VDIsWindowsNT()) {
  251.         LVITEMW itemw = {};
  252.  
  253.         itemw.mask        = LVIF_TEXT | LVIF_PARAM;
  254.         itemw.iItem        = item;
  255.         itemw.pszText    = LPSTR_TEXTCALLBACKW;
  256.         itemw.lParam    = (LPARAM)lvvi;
  257.  
  258.         index = (int)SendMessageW(mhwnd, LVM_INSERTITEMW, 0, (LPARAM)&itemw);
  259.     } else {
  260.         LVITEMA itema = {};
  261.  
  262.         itema.mask        = LVIF_TEXT | LVIF_PARAM;
  263.         itema.iItem        = item;
  264.         itema.pszText    = LPSTR_TEXTCALLBACKA;
  265.         itema.lParam    = (LPARAM)lvvi;
  266.  
  267.         index = (int)SendMessageA(mhwnd, LVM_INSERTITEMA, 0, (LPARAM)&itema);
  268.     }
  269.  
  270.     if (index >= 0)
  271.         lvvi->AddRef();
  272.  
  273.     return index;
  274. }
  275.  
  276. void VDUIProxyListView::RefreshItem(int item) {
  277.     SendMessage(mhwnd, LVM_REDRAWITEMS, item, item);
  278. }
  279.  
  280. void VDUIProxyListView::SetItemText(int item, int subitem, const wchar_t *text) {
  281.     if (VDIsWindowsNT()) {
  282.         LVITEMW itemw = {};
  283.  
  284.         itemw.mask        = LVIF_TEXT;
  285.         itemw.iItem        = item;
  286.         itemw.iSubItem    = subitem;
  287.         itemw.pszText    = (LPWSTR)text;
  288.  
  289.         SendMessageW(mhwnd, LVM_SETITEMW, 0, (LPARAM)&itemw);
  290.     } else {
  291.         LVITEMA itema = {};
  292.         VDStringA texta(VDTextWToA(text));
  293.  
  294.         itema.mask        = LVIF_TEXT;
  295.         itema.iItem        = item;
  296.         itema.iSubItem    = subitem;
  297.         itema.pszText    = (LPSTR)texta.c_str();
  298.  
  299.         SendMessageA(mhwnd, LVM_SETITEMA, 0, (LPARAM)&itema);
  300.     }
  301. }
  302.  
  303. VDZLRESULT VDUIProxyListView::On_WM_NOTIFY(VDZWPARAM wParam, VDZLPARAM lParam) {
  304.     const NMHDR *hdr = (const NMHDR *)lParam;
  305.  
  306.     switch(hdr->code) {
  307.         case LVN_GETDISPINFOA:
  308.             {
  309.                 NMLVDISPINFOA *dispa = (NMLVDISPINFOA *)hdr;
  310.                 IVDUIListViewVirtualItem *lvvi = (IVDUIListViewVirtualItem *)dispa->item.lParam;
  311.  
  312.                 mTextW[0].clear();
  313.                 lvvi->GetText(dispa->item.iSubItem, mTextW[0]);
  314.                 mTextA[mNextTextIndex] = VDTextWToA(mTextW[0]);
  315.                 dispa->item.pszText = (LPSTR)mTextA[mNextTextIndex].c_str();
  316.  
  317.                 if (++mNextTextIndex >= 3)
  318.                     mNextTextIndex = 0;
  319.             }
  320.             break;
  321.  
  322.         case LVN_GETDISPINFOW:
  323.             {
  324.                 NMLVDISPINFOW *dispw = (NMLVDISPINFOW *)hdr;
  325.                 IVDUIListViewVirtualItem *lvvi = (IVDUIListViewVirtualItem *)dispw->item.lParam;
  326.  
  327.                 mTextW[mNextTextIndex].clear();
  328.                 lvvi->GetText(dispw->item.iSubItem, mTextW[mNextTextIndex]);
  329.                 dispw->item.pszText = (LPWSTR)mTextW[mNextTextIndex].c_str();
  330.  
  331.                 if (++mNextTextIndex >= 3)
  332.                     mNextTextIndex = 0;
  333.             }
  334.             break;
  335.  
  336.         case LVN_DELETEITEM:
  337.             {
  338.                 const NMLISTVIEW *nmlv = (const NMLISTVIEW *)hdr;
  339.                 IVDUIListViewVirtualItem *lvvi = (IVDUIListViewVirtualItem *)nmlv->lParam;
  340.  
  341.                 if (lvvi)
  342.                     lvvi->Release();
  343.             }
  344.             break;
  345.  
  346.         case LVN_COLUMNCLICK:
  347.             {
  348.                 const NMLISTVIEW *nmlv = (const NMLISTVIEW *)hdr;
  349.  
  350.                 mEventColumnClicked.Raise(this, nmlv->iSubItem);
  351.             }
  352.             break;
  353.  
  354.         case LVN_ITEMCHANGED:
  355.             {
  356.                 const NMLISTVIEW *nmlv = (const NMLISTVIEW *)hdr;
  357.  
  358.                 if (nmlv->uChanged & LVIF_STATE) {
  359.                     int selIndex = ListView_GetNextItem(mhwnd, -1, LVNI_ALL | LVNI_SELECTED);
  360.  
  361.                     mEventItemSelectionChanged.Raise(this, selIndex);
  362.                 }
  363.             }
  364.             break;
  365.     }
  366.  
  367.     return 0;
  368. }
  369.  
  370. ///////////////////////////////////////////////////////////////////////////
  371.  
  372. VDUIProxyHotKeyControl::VDUIProxyHotKeyControl() {
  373. }
  374.  
  375. VDUIProxyHotKeyControl::~VDUIProxyHotKeyControl() {
  376. }
  377.  
  378. bool VDUIProxyHotKeyControl::GetAccelerator(VDUIAccelerator& accel) const {
  379.     if (!mhwnd)
  380.         return false;
  381.  
  382.     uint32 v = SendMessage(mhwnd, HKM_GETHOTKEY, 0, 0);
  383.  
  384.     accel.mVirtKey = (uint8)v;
  385.     accel.mModifiers = 0;
  386.     
  387.     const uint8 mods = (uint8)(v >> 8);
  388.     if (mods & HOTKEYF_SHIFT)
  389.         accel.mModifiers |= VDUIAccelerator::kModShift;
  390.  
  391.     if (mods & HOTKEYF_CONTROL)
  392.         accel.mModifiers |= VDUIAccelerator::kModCtrl;
  393.  
  394.     if (mods & HOTKEYF_ALT)
  395.         accel.mModifiers |= VDUIAccelerator::kModAlt;
  396.  
  397.     if (mods & HOTKEYF_EXT)
  398.         accel.mModifiers |= VDUIAccelerator::kModExtended;
  399.  
  400.     return true;
  401. }
  402.  
  403. void VDUIProxyHotKeyControl::SetAccelerator(const VDUIAccelerator& accel) {
  404.     uint32 mods = 0;
  405.  
  406.     if (accel.mModifiers & VDUIAccelerator::kModShift)
  407.         mods |= HOTKEYF_SHIFT;
  408.  
  409.     if (accel.mModifiers & VDUIAccelerator::kModCtrl)
  410.         mods |= HOTKEYF_CONTROL;
  411.  
  412.     if (accel.mModifiers & VDUIAccelerator::kModAlt)
  413.         mods |= HOTKEYF_ALT;
  414.  
  415.     if (accel.mModifiers & VDUIAccelerator::kModExtended)
  416.         mods |= HOTKEYF_EXT;
  417.  
  418.     SendMessage(mhwnd, HKM_SETHOTKEY, accel.mVirtKey + (mods << 8), 0);
  419. }
  420.  
  421. VDZLRESULT VDUIProxyHotKeyControl::On_WM_COMMAND(VDZWPARAM wParam, VDZLPARAM lParam) {
  422.     if (HIWORD(wParam) == EN_CHANGE) {
  423.         VDUIAccelerator accel;
  424.         GetAccelerator(accel);
  425.         mEventHotKeyChanged.Raise(this, accel);
  426.     }
  427.  
  428.     return 0;
  429. }
  430.