| Left: | ||
| Right: |
| LEFT | RIGHT |
|---|---|
| 1 #include "PluginStdAfx.h" | 1 #include "PluginStdAfx.h" |
| 2 | 2 |
| 3 #include "PluginClass.h" | 3 #include "PluginClass.h" |
| 4 #include "PluginSettings.h" | 4 #include "PluginSettings.h" |
| 5 #include "PluginSystem.h" | 5 #include "PluginSystem.h" |
| 6 #ifdef SUPPORT_FILTER | 6 #ifdef SUPPORT_FILTER |
| 7 #include "PluginFilter.h" | 7 #include "PluginFilter.h" |
| 8 #endif | 8 #endif |
| 9 #include "PluginMimeFilterClient.h" | 9 #include "PluginMimeFilterClient.h" |
| 10 #include "PluginClient.h" | 10 #include "PluginClient.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 42 CComAutoCriticalSection CPluginClass::s_criticalSectionLocal; | 42 CComAutoCriticalSection CPluginClass::s_criticalSectionLocal; |
| 43 CComAutoCriticalSection CPluginClass::s_criticalSectionBrowser; | 43 CComAutoCriticalSection CPluginClass::s_criticalSectionBrowser; |
| 44 CComAutoCriticalSection CPluginClass::s_criticalSectionWindow; | 44 CComAutoCriticalSection CPluginClass::s_criticalSectionWindow; |
| 45 | 45 |
| 46 CComQIPtr<IWebBrowser2> CPluginClass::s_asyncWebBrowser2; | 46 CComQIPtr<IWebBrowser2> CPluginClass::s_asyncWebBrowser2; |
| 47 | 47 |
| 48 #ifdef SUPPORT_WHITELIST | 48 #ifdef SUPPORT_WHITELIST |
| 49 std::map<UINT,CString> CPluginClass::s_menuDomains; | 49 std::map<UINT,CString> CPluginClass::s_menuDomains; |
| 50 #endif | 50 #endif |
| 51 | 51 |
| 52 /* | |
| 53 * Without namespace declaration, the identifier "Rectangle" is ambiguous | |
| 54 * See http://msdn.microsoft.com/en-us/library/windows/desktop/dd162898(v=vs.85) .aspx | |
| 55 */ | |
| 56 namespace AdblockPlus | |
| 57 { | |
| 58 /** | |
| 59 * Replacement for ATL type CRect. | |
| 60 */ | |
| 61 class Rectangle | |
| 62 : public RECT | |
| 63 { | |
| 64 public: | |
| 65 int Height() const | |
| 66 { | |
| 67 return bottom - top; | |
| 68 } | |
| 69 | |
| 70 int Width() const | |
| 71 { | |
| 72 return right - left; | |
| 73 } | |
| 74 }; | |
| 75 } | |
| 52 | 76 |
| 53 CPluginClass::CPluginClass() | 77 CPluginClass::CPluginClass() |
| 54 { | 78 { |
| 55 //Use this line to debug memory leaks | 79 //Use this line to debug memory leaks |
| 56 // _CrtDumpMemoryLeaks(); | 80 // _CrtDumpMemoryLeaks(); |
| 57 | 81 |
| 58 m_isAdviced = false; | 82 m_isAdviced = false; |
| 59 m_nConnectionID = 0; | 83 m_nConnectionID = 0; |
| 60 m_hTabWnd = NULL; | 84 m_hTabWnd = NULL; |
| 61 m_hStatusBarWnd = NULL; | 85 m_hStatusBarWnd = NULL; |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 254 | 278 |
| 255 //register the mimefilter | 279 //register the mimefilter |
| 256 //and only mimefilter | 280 //and only mimefilter |
| 257 //on some few computers the mimefilter does not get properly registered when it is done on another thread | 281 //on some few computers the mimefilter does not get properly registered when it is done on another thread |
| 258 | 282 |
| 259 s_criticalSectionLocal.Lock(); | 283 s_criticalSectionLocal.Lock(); |
| 260 { | 284 { |
| 261 // Always register on startup, then check if we need to unregister in a se parate thread | 285 // Always register on startup, then check if we need to unregister in a se parate thread |
| 262 s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); | 286 s_mimeFilter = CPluginClientFactory::GetMimeFilterClientInstance(); |
| 263 s_asyncWebBrowser2 = unknownSite; | 287 s_asyncWebBrowser2 = unknownSite; |
| 264 s_instances.insert( this ); | 288 s_instances.insert(this); |
|
Oleksandr
2014/07/21 09:00:54
Style nit: no space after '(' and before ')'
| |
| 265 } | 289 } |
| 266 s_criticalSectionLocal.Unlock(); | 290 s_criticalSectionLocal.Unlock(); |
| 267 | 291 |
| 268 try | 292 try |
| 269 { | 293 { |
| 270 // Check if loaded as BHO | 294 // Check if loaded as BHO |
| 271 if (GetBrowser()) | 295 if (GetBrowser()) |
| 272 { | 296 { |
| 273 DEBUG_GENERAL("Loaded as BHO"); | 297 DEBUG_GENERAL("Loaded as BHO"); |
| 274 CComPtr<IConnectionPoint> pPoint = GetConnectionPoint(); | 298 CComPtr<IConnectionPoint> pPoint = GetConnectionPoint(); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 365 | 389 |
| 366 s_criticalSectionLocal.Lock(); | 390 s_criticalSectionLocal.Lock(); |
| 367 { | 391 { |
| 368 s_instances.erase(this); | 392 s_instances.erase(this); |
| 369 | 393 |
| 370 std::map<DWORD,CPluginClass*>::iterator it = s_threadInstances.find(::GetC urrentThreadId()); | 394 std::map<DWORD,CPluginClass*>::iterator it = s_threadInstances.find(::GetC urrentThreadId()); |
| 371 if (it != s_threadInstances.end()) | 395 if (it != s_threadInstances.end()) |
| 372 { | 396 { |
| 373 s_threadInstances.erase(it); | 397 s_threadInstances.erase(it); |
| 374 } | 398 } |
| 375 if ( s_instances.empty() ) | 399 if (s_instances.empty()) |
|
Oleksandr
2014/07/21 09:00:54
Style nit: no space after '(' and before ')'
| |
| 376 { | 400 { |
| 377 CPluginClientFactory::ReleaseMimeFilterClientInstance(); | 401 CPluginClientFactory::ReleaseMimeFilterClientInstance(); |
| 378 } | 402 } |
| 379 } | 403 } |
| 380 s_criticalSectionLocal.Unlock(); | 404 s_criticalSectionLocal.Unlock(); |
| 381 | 405 |
| 382 // Release browser interface | 406 // Release browser interface |
| 383 s_criticalSectionBrowser.Lock(); | 407 s_criticalSectionBrowser.Lock(); |
| 384 { | 408 { |
| 385 m_webBrowser2.Release(); | 409 m_webBrowser2.Release(); |
| (...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 886 if (hTabWnd2) | 910 if (hTabWnd2) |
| 887 { | 911 { |
| 888 DWORD nProcessId; | 912 DWORD nProcessId; |
| 889 ::GetWindowThreadProcessId(hTabWnd2, &nProcessId); | 913 ::GetWindowThreadProcessId(hTabWnd2, &nProcessId); |
| 890 if (::GetCurrentProcessId() == nProcessId) | 914 if (::GetCurrentProcessId() == nProcessId) |
| 891 { | 915 { |
| 892 bool bExistingTab = false; | 916 bool bExistingTab = false; |
| 893 | 917 |
| 894 s_criticalSectionLocal.Lock(); | 918 s_criticalSectionLocal.Lock(); |
| 895 { | 919 { |
| 896 for ( auto instance : s_instances ) | 920 for (auto instance : s_instances) |
|
Oleksandr
2014/07/21 09:00:54
Style nit: no space after '(' and before ')'
| |
| 897 { | 921 { |
| 898 if ( instance->m_hTabWnd == hTabWnd2) | 922 if (instance->m_hTabWnd == hTabWnd2) |
|
Oleksandr
2014/07/21 09:00:54
Style nit: no space after '('
| |
| 899 { | 923 { |
| 900 | |
| 901 bExistingTab = true; | 924 bExistingTab = true; |
| 902 break; | 925 break; |
| 903 } | 926 } |
| 904 } | 927 } |
| 905 } | 928 } |
| 906 s_criticalSectionLocal.Unlock(); | 929 s_criticalSectionLocal.Unlock(); |
| 907 | 930 |
| 908 if (!bExistingTab) | 931 if (!bExistingTab) |
| 909 { | 932 { |
| 910 amoundOfNewTabs ++; | 933 amoundOfNewTabs ++; |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 938 hWnd = ::GetWindow(hWnd, GW_HWNDNEXT); | 961 hWnd = ::GetWindow(hWnd, GW_HWNDNEXT); |
| 939 } | 962 } |
| 940 | 963 |
| 941 if (!hWndStatusBar) | 964 if (!hWndStatusBar) |
| 942 { | 965 { |
| 943 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_NO_STATUSBAR_WIN, "Class ::CreateStatusBarPane - No status bar") | 966 DEBUG_ERROR_LOG(0, PLUGIN_ERROR_UI, PLUGIN_ERROR_UI_NO_STATUSBAR_WIN, "Class ::CreateStatusBarPane - No status bar") |
| 944 return true; | 967 return true; |
| 945 } | 968 } |
| 946 | 969 |
| 947 // Calculate pane height | 970 // Calculate pane height |
| 948 CRect rcStatusBar; | 971 AdblockPlus::Rectangle rcStatusBar; |
| 949 ::GetClientRect(hWndStatusBar, &rcStatusBar); | 972 ::GetClientRect(hWndStatusBar, &rcStatusBar); |
| 950 | 973 |
| 951 if (rcStatusBar.Height() > 0) | 974 if (rcStatusBar.Height() > 0) |
| 952 { | 975 { |
| 953 #ifdef _DEBUG | 976 #ifdef _DEBUG |
| 954 m_nPaneWidth = 70; | 977 m_nPaneWidth = 70; |
| 955 #else | 978 #else |
| 956 m_nPaneWidth = min(rcStatusBar.Height(), 22); | 979 m_nPaneWidth = min(rcStatusBar.Height(), 22); |
| 957 #endif | 980 #endif |
| 958 } | 981 } |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1055 m_hTheme = pfnOpenThemeData(m_hPaneWnd, L"STATUS"); | 1078 m_hTheme = pfnOpenThemeData(m_hPaneWnd, L"STATUS"); |
| 1056 if (!m_hTheme) | 1079 if (!m_hTheme) |
| 1057 { | 1080 { |
| 1058 } | 1081 } |
| 1059 } | 1082 } |
| 1060 } | 1083 } |
| 1061 | 1084 |
| 1062 | 1085 |
| 1063 CPluginClass* CPluginClass::FindInstance(HWND hStatusBarWnd) | 1086 CPluginClass* CPluginClass::FindInstance(HWND hStatusBarWnd) |
| 1064 { | 1087 { |
| 1065 CPluginClass* return_instance = NULL; | 1088 CPluginClass* result = nullptr; |
|
sergei
2014/07/21 08:49:51
According to the coding style it should be `nullpt
| |
| 1066 | 1089 |
| 1067 s_criticalSectionLocal.Lock(); | 1090 s_criticalSectionLocal.Lock(); |
| 1068 { | 1091 { |
| 1069 for ( auto instance : s_instances ) | 1092 for (auto instance : s_instances) |
|
Oleksandr
2014/07/21 09:00:54
Style nit: no space after '(' and before ')'
| |
| 1070 { | 1093 { |
| 1071 if ( instance->m_hStatusBarWnd == hStatusBarWnd) | 1094 if (instance->m_hStatusBarWnd == hStatusBarWnd) |
|
Oleksandr
2014/07/21 09:00:54
Style nit: no space after '('
| |
| 1072 { | 1095 { |
| 1073 return_instance = instance; | 1096 result = instance; |
| 1074 break; | 1097 break; |
| 1075 } | 1098 } |
| 1076 } | 1099 } |
| 1077 } | 1100 } |
| 1078 s_criticalSectionLocal.Unlock(); | 1101 s_criticalSectionLocal.Unlock(); |
| 1079 | 1102 |
| 1080 return return_instance; | 1103 return result; |
| 1081 } | 1104 } |
| 1082 | 1105 |
| 1083 CPluginTab* CPluginClass::GetTab() | 1106 CPluginTab* CPluginClass::GetTab() |
| 1084 { | 1107 { |
| 1085 return m_tab; | 1108 return m_tab; |
| 1086 } | 1109 } |
| 1087 | 1110 |
| 1088 CPluginTab* CPluginClass::GetTab(DWORD dwThreadId) | 1111 CPluginTab* CPluginClass::GetTab(DWORD dwThreadId) |
| 1089 { | 1112 { |
| 1090 CPluginTab* tab = NULL; | 1113 CPluginTab* tab = NULL; |
| (...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1569 HLOCAL hLocal = LocalAlloc(LHND, sizeof(int) * (nParts+1)); | 1592 HLOCAL hLocal = LocalAlloc(LHND, sizeof(int) * (nParts+1)); |
| 1570 LPINT lpParts = (LPINT)LocalLock(hLocal); | 1593 LPINT lpParts = (LPINT)LocalLock(hLocal); |
| 1571 memcpy(lpParts, (void*)lParam, wParam*sizeof(int)); | 1594 memcpy(lpParts, (void*)lParam, wParam*sizeof(int)); |
| 1572 | 1595 |
| 1573 for (unsigned i = 0; i < STATUSBAR_PANE_NUMBER; i++) | 1596 for (unsigned i = 0; i < STATUSBAR_PANE_NUMBER; i++) |
| 1574 { | 1597 { |
| 1575 lpParts[i] -= pClass->m_nPaneWidth; | 1598 lpParts[i] -= pClass->m_nPaneWidth; |
| 1576 } | 1599 } |
| 1577 LRESULT hRet = CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wPa ram, (LPARAM)lpParts); | 1600 LRESULT hRet = CallWindowProc(pClass->m_pWndProcStatus, hWnd, message, wPa ram, (LPARAM)lpParts); |
| 1578 | 1601 |
| 1579 CRect rcPane; | 1602 AdblockPlus::Rectangle rcPane; |
| 1580 ::SendMessage(hWnd, SB_GETRECT, STATUSBAR_PANE_NUMBER, (LPARAM)&rcPane); | 1603 ::SendMessage(hWnd, SB_GETRECT, STATUSBAR_PANE_NUMBER, (LPARAM)&rcPane); |
| 1581 | 1604 |
| 1582 CRect rcClient; | 1605 AdblockPlus::Rectangle rcClient; |
| 1583 ::GetClientRect(hWnd, &rcClient); | 1606 ::GetClientRect(hWnd, &rcClient); |
| 1584 | 1607 |
| 1585 ::MoveWindow( | 1608 ::MoveWindow( |
| 1586 pClass->m_hPaneWnd, | 1609 pClass->m_hPaneWnd, |
| 1587 lpParts[STATUSBAR_PANE_NUMBER] - pClass->m_nPaneWidth, | 1610 lpParts[STATUSBAR_PANE_NUMBER] - pClass->m_nPaneWidth, |
| 1588 0, | 1611 0, |
| 1589 pClass->m_nPaneWidth, | 1612 pClass->m_nPaneWidth, |
| 1590 rcClient.Height(), | 1613 rcClient.Height(), |
| 1591 TRUE); | 1614 TRUE); |
| 1592 | 1615 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1659 case WM_SETCURSOR: | 1682 case WM_SETCURSOR: |
| 1660 { | 1683 { |
| 1661 ::SetCursor(::LoadCursor(NULL, IDC_ARROW)); | 1684 ::SetCursor(::LoadCursor(NULL, IDC_ARROW)); |
| 1662 return TRUE; | 1685 return TRUE; |
| 1663 } | 1686 } |
| 1664 case WM_PAINT: | 1687 case WM_PAINT: |
| 1665 { | 1688 { |
| 1666 PAINTSTRUCT ps; | 1689 PAINTSTRUCT ps; |
| 1667 HDC hDC = ::BeginPaint(hWnd, &ps); | 1690 HDC hDC = ::BeginPaint(hWnd, &ps); |
| 1668 | 1691 |
| 1669 CRect rcClient; | 1692 AdblockPlus::Rectangle rcClient; |
| 1670 ::GetClientRect(hWnd, &rcClient); | 1693 ::GetClientRect(hWnd, &rcClient); |
| 1671 | 1694 |
| 1672 int nDrawEdge = 0; | 1695 int nDrawEdge = 0; |
| 1673 | 1696 |
| 1674 // Old Windows background drawing | 1697 // Old Windows background drawing |
| 1675 if (pClass->m_hTheme == NULL) | 1698 if (pClass->m_hTheme == NULL) |
| 1676 { | 1699 { |
| 1677 ::FillRect(hDC, &rcClient, (HBRUSH)(COLOR_BTNFACE + 1)); | 1700 ::FillRect(hDC, &rcClient, (HBRUSH)(COLOR_BTNFACE + 1)); |
| 1678 ::DrawEdge(hDC, &rcClient, BDR_RAISEDINNER, BF_LEFT); | 1701 ::DrawEdge(hDC, &rcClient, BDR_RAISEDINNER, BF_LEFT); |
| 1679 | 1702 |
| 1680 nDrawEdge = 3; | 1703 nDrawEdge = 3; |
| 1681 rcClient.left += 3; | 1704 rcClient.left += 3; |
| 1682 | 1705 |
| 1683 ::DrawEdge(hDC, &rcClient, BDR_SUNKENOUTER, BF_RECT); | 1706 ::DrawEdge(hDC, &rcClient, BDR_SUNKENOUTER, BF_RECT); |
| 1684 } | 1707 } |
| 1685 // Themed background drawing | 1708 // Themed background drawing |
| 1686 else | 1709 else |
| 1687 { | 1710 { |
| 1688 // Draw background | 1711 // Draw background |
| 1689 if (pfnDrawThemeBackground) | 1712 if (pfnDrawThemeBackground) |
| 1690 { | 1713 { |
| 1691 CRect rc = rcClient; | 1714 AdblockPlus::Rectangle rc = rcClient; |
| 1692 rc.right -= 2; | 1715 rc.right -= 2; |
| 1693 pfnDrawThemeBackground(pClass->m_hTheme, hDC, 0, 0, &rc, NULL); | 1716 pfnDrawThemeBackground(pClass->m_hTheme, hDC, 0, 0, &rc, NULL); |
| 1694 } | 1717 } |
| 1695 | 1718 |
| 1696 // Copy separator picture to left side | 1719 // Copy separator picture to left side |
| 1697 int nHeight = rcClient.Height(); | 1720 int nHeight = rcClient.Height(); |
| 1698 int nWidth = rcClient.Width() - 2; | 1721 int nWidth = rcClient.Width() - 2; |
| 1699 | 1722 |
| 1700 for (int i = 0; i < 2; i++) | 1723 for (int i = 0; i < 2; i++) |
| 1701 { | 1724 { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1721 if (hIcon) | 1744 if (hIcon) |
| 1722 { | 1745 { |
| 1723 ::DrawIconEx(hDC, offx, (rcClient.Height() - 16)/2 + 2, hIcon, 16, 16, NULL, NULL, DI_NORMAL); | 1746 ::DrawIconEx(hDC, offx, (rcClient.Height() - 16)/2 + 2, hIcon, 16, 16, NULL, NULL, DI_NORMAL); |
| 1724 offx += 22; | 1747 offx += 22; |
| 1725 } | 1748 } |
| 1726 #ifdef _DEBUG | 1749 #ifdef _DEBUG |
| 1727 // Display version | 1750 // Display version |
| 1728 HFONT hFont = (HFONT)::SendMessage(pClass->m_hStatusBarWnd, WM_GETFONT, 0, 0); | 1751 HFONT hFont = (HFONT)::SendMessage(pClass->m_hStatusBarWnd, WM_GETFONT, 0, 0); |
| 1729 HGDIOBJ hOldFont = ::SelectObject(hDC,hFont); | 1752 HGDIOBJ hOldFont = ::SelectObject(hDC,hFont); |
| 1730 | 1753 |
| 1731 CRect rcText = rcClient; | 1754 AdblockPlus::Rectangle rcText = rcClient; |
| 1732 rcText.left += offx; | 1755 rcText.left += offx; |
| 1733 ::SetBkMode(hDC, TRANSPARENT); | 1756 ::SetBkMode(hDC, TRANSPARENT); |
| 1734 ::DrawTextW(hDC, IEPLUGIN_VERSION, -1, &rcText, DT_WORD_ELLIPSIS|DT_LEFT |DT_SINGLELINE|DT_VCENTER); | 1757 ::DrawTextW(hDC, IEPLUGIN_VERSION, -1, &rcText, DT_WORD_ELLIPSIS|DT_LEFT |DT_SINGLELINE|DT_VCENTER); |
| 1735 | 1758 |
| 1736 ::SelectObject(hDC, hOldFont); | 1759 ::SelectObject(hDC, hOldFont); |
| 1737 #endif // _DEBUG | 1760 #endif // _DEBUG |
| 1738 } | 1761 } |
| 1739 | 1762 |
| 1740 // Done! | 1763 // Done! |
| 1741 EndPaint(hWnd, &ps); | 1764 EndPaint(hWnd, &ps); |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1942 if (hTabWnd2) | 1965 if (hTabWnd2) |
| 1943 { | 1966 { |
| 1944 DWORD nProcessId; | 1967 DWORD nProcessId; |
| 1945 ::GetWindowThreadProcessId(hTabWnd2, &nProcessId); | 1968 ::GetWindowThreadProcessId(hTabWnd2, &nProcessId); |
| 1946 if (::GetCurrentProcessId() == nProcessId) | 1969 if (::GetCurrentProcessId() == nProcessId) |
| 1947 { | 1970 { |
| 1948 bool bExistingTab = false; | 1971 bool bExistingTab = false; |
| 1949 s_criticalSectionLocal.Lock(); | 1972 s_criticalSectionLocal.Lock(); |
| 1950 | 1973 |
| 1951 { | 1974 { |
| 1952 for ( auto instance : s_instances ) | 1975 for (auto instance : s_instances) |
|
Oleksandr
2014/07/21 09:00:54
Style nit: no space after '(' and before ')'
| |
| 1953 { | 1976 { |
| 1954 if ( instance->m_hTabWnd == hTabWnd2 ) | 1977 if (instance->m_hTabWnd == hTabWnd2) |
|
Oleksandr
2014/07/21 09:00:54
Style nit: no space after '(' and before ')'
| |
| 1955 { | 1978 { |
| 1956 bExistingTab = true; | 1979 bExistingTab = true; |
| 1957 break; | 1980 break; |
| 1958 } | 1981 } |
| 1959 } | 1982 } |
| 1960 } | 1983 } |
| 1961 | 1984 |
| 1962 if (!bExistingTab) | 1985 if (!bExistingTab) |
| 1963 { | 1986 { |
| 1964 hBrowserWnd = hTabWnd2; | 1987 hBrowserWnd = hTabWnd2; |
| 1965 hTabWnd = hTabWnd2; | 1988 hTabWnd = hTabWnd2; |
| 1966 s_criticalSectionLocal.Unlock(); | 1989 s_criticalSectionLocal.Unlock(); |
| 1967 break; | 1990 break; |
| 1968 } | 1991 } |
| 1969 s_criticalSectionLocal.Unlock(); | 1992 s_criticalSectionLocal.Unlock(); |
| 1970 | 1993 |
| 1971 } | 1994 } |
| 1972 } | 1995 } |
| 1973 } | 1996 } |
| 1974 | 1997 |
| 1975 hTabWnd = ::GetWindow(hTabWnd, GW_HWNDNEXT); | 1998 hTabWnd = ::GetWindow(hTabWnd, GW_HWNDNEXT); |
| 1976 } | 1999 } |
| 1977 | 2000 |
| 1978 return hTabWnd; | 2001 return hTabWnd; |
| 1979 | 2002 |
| 1980 } | 2003 } |
| LEFT | RIGHT |