#include <afxtempl.h> // MFC template collection classes
#include <afxext.h> // needed for CFormView
-#ifndef NOSUBCLASS
-#include "CSubclass.h"
-#endif // NOSUBCLASS
-
-
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
CMoveConstraint::CMoveConstraint()
{
m_bSubclassed = false;
+ m_oldWndProc = NULL;
m_sRegistryValueName = _T("UnnamedWindow");
m_sRegistrySubkey = _T("LastWindowPos");
ClearMostData();
bool
CMoveConstraint::InitializeCurrentSize(HWND hwndDlg)
{
-ASSERT(!m_hwndDlg);
+ ASSERT(!m_hwndDlg);
if (!IsWindow(hwndDlg))
return false;
m_hwndDlg = hwndDlg;
}
/**
- * Chain to further CSubclass processing if appropriate
- */
-LRESULT
-CMoveConstraint::CallOriginalProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
-#ifndef NOSUBCLASS
- if (m_bSubclassed)
- return CallOldProc(ConstraintWndProc, hwnd, msg, wParam, lParam);
-#else
- if (0)
- ;
-#endif // NOSUBCLASS
- else
- return (LRESULT)0;
-}
-
-#ifndef NOSUBCLASS
-/**
* This is the window proc callback that works with the CSubclass module.
*/
LRESULT CALLBACK
CMoveConstraint::ConstraintWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
- void * data = GetData(ConstraintWndProc, hwnd);
+ void * data = GetProp(hwnd, _T("CMoveConstraintData"));
CMoveConstraint * constraint = reinterpret_cast<CMoveConstraint *>(data);
LRESULT lresult;
if (constraint->WindowProc(hwnd, msg, wParam, lParam, &lresult))
return lresult;
- return constraint->CallOriginalProc(hwnd, msg, wParam, lParam);
+ return CallWindowProc(constraint->m_oldWndProc, hwnd, msg, wParam, lParam);
}
bool
CMoveConstraint::SubclassWnd()
void * data = reinterpret_cast<void *>(this);
// this will return false if this window/wndproc combination has already
// been established (subclassed)
- m_bSubclassed = Subclass(ConstraintWndProc, m_hwndDlg, data);
+ m_bSubclassed = true;
+ m_oldWndProc = reinterpret_cast<WNDPROC>(GetWindowLongPtr(m_hwndDlg, GWLP_WNDPROC));
+ SetWindowLongPtr(m_hwndDlg, GWLP_WNDPROC, (__int3264)(LONG_PTR)(CMoveConstraint::ConstraintWndProc));
+ SetProp(m_hwndDlg, _T("CMoveConstraintData"), data);
return m_bSubclassed;
}
bool
CMoveConstraint::UnSubclassWnd()
{
- return UnSubclass(ConstraintWndProc, m_hwndDlg);
+ if (!m_bSubclassed)
+ return false;
+ SetWindowLongPtr(m_hwndDlg, GWLP_WNDPROC, (__int3264)(LONG_PTR)(m_oldWndProc));
+ RemoveProp(m_hwndDlg, _T("CMoveConstraintData"));
+ m_oldWndProc = NULL;
+ m_bSubclassed = false;
+ return true;
}
-#endif
/**
* Check if we have any pending constraints not yet added to constraint list
lpMMI->ptMaxTrackSize.y = m_nMaxY;
}
-/**
- * Client is asking for window proc handling for a property page.
- */
-bool
-CMoveConstraint::WindowProcPropertyPage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT * plresult)
-{
- m_bPropertyPage = true;
- return WindowProc(hWnd, message, wParam, lParam, plresult);
-}
-
-/**
- * Client is asking for window proc handling for a property sheet.
- */
-bool
-CMoveConstraint::WindowProcPropertySheet(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT * plresult)
-{
- m_bPropertySheet = true;
- return WindowProc(hWnd, message, wParam, lParam, plresult);
-}
-
bool
CMoveConstraint::PaintGrip()
{
return false;
if (m_nMinY == m_nMaxY)
{
- LRESULT nRet = CallOriginalProc(m_hwndDlg, msg, wParam, lParam);
+ LRESULT nRet = CallWindowProc(m_oldWndProc, m_hwndDlg, msg, wParam, lParam);
switch(nRet)
{
case HTBOTTOMLEFT:
}
if (m_nMinX == m_nMaxX)
{
- LRESULT nRet = CallOriginalProc(m_hwndDlg, msg, wParam, lParam);
+ LRESULT nRet = CallWindowProc(m_oldWndProc, m_hwndDlg, msg, wParam, lParam);
switch(nRet)
{
case HTBOTTOMLEFT:
{
if (m_bPersistent)
Persist(true, true);
+ UnSubclassWnd();
// the one variable that CANNOT safely be cleared now is m_bSubclassed
// because the subclass is almost certainly not yet removed
// (the subclass calls us to let us do destroy processing, before
// see usage section above
bool WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT * plresult);
- // obsolete now 2000/10/06
- // (use SetIsPropertyPage etc, and WindowProc above, or just Subclass)
- bool WindowProcPropertyPage(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT * plresult);
- bool WindowProcPropertySheet(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT * plresult);
// ToolTips
void SetTip(int id, LPCTSTR szTip);
bool OnNcHitTest(UINT message, WPARAM wParam, LPARAM lParam, LRESULT * plresult);
// handle WM_NOTIFY/TTN_NEEDTEXT combination
bool OnTtnNeedText(TOOLTIPTEXT * pTTT, LRESULT * plresult);
- // forwarder
- LRESULT CallOriginalProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
bool PaintGrip();
void ClearMostData();
void DeleteAllConstraints();
int m_nMaxY;
int m_nDelayed; // CWnds without HWND
bool m_bSubclassed;
+ WNDPROC m_oldWndProc;
// formview stuff
CFormView * m_pFormView;
// formview original scrollbars
+++ /dev/null
-/*!
- \file CSubclass.cpp
- \author Perry Rapp, Creator, 1998-2003
- \date Created: 1998
- \date Edited: 2006/09/20 Kimmo Varis: use Get/SetWindowLongPtr().
-
- \brief Implementation of CSubclass
-
-*/
-/* The MIT License
-Copyright (c) 2001 Perry Rapp
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-
-#include "StdAfx.h"
-#include "CSubclass.h"
-
-#include <afxtempl.h>
-
-#ifdef _DEBUG
-#define new DEBUG_NEW
-#undef THIS_FILE
-static char THIS_FILE[] = __FILE__;
-#endif
-
-namespace prdlg {
-
-struct SubclassRec
-{
- WNDPROC m_newproc;
- WNDPROC m_oldproc;
- void * m_data;
- bool m_suppressing; // set during the failed message
- Msg m_succeededMsg;
- Msg m_failedMsg;
-};
-
-// all the subclasses for a given hwnd
-// newest is head
-typedef CList<SubclassRec, SubclassRec &> SubclassList;
-
-// map of hwnds to subclasses
-typedef CTypedPtrMap<CMapPtrToPtr, HWND, SubclassList*> SubclassMap;
-
-#ifdef _MT
-#define THREAD _declspec(thread)
-#else
-#define THREAD
-#endif
-// map of hwnds to subclasses for current thread
-static THREAD SubclassMap * f_Subclasses=0;
-
-
-
-bool Subclass(WNDPROC wndproc, HWND hwnd, void * data
- , Msg * unsubclassSucceeded, Msg * unsubclassFailed)
-{
- ASSERT(IsWindow(hwnd));
- // cross-thread window usage is not kosher ?
- ASSERT(GetCurrentThreadId() == GetWindowThreadProcessId(hwnd, 0));
- if (!f_Subclasses)
- f_Subclasses = new SubclassMap;
- SubclassList *pList = 0;
- if (f_Subclasses->Lookup(hwnd, pList))
- { // we've already subclassed this window
- for (POSITION pos = pList->GetHeadPosition(); pos; pList->GetNext(pos))
- {
- SubclassRec & srec = pList->GetAt(pos);
- if (srec.m_newproc == wndproc)
- return false; // cannot resubclass with same WNDPROC
- }
- }
- else
- {
- pList = new SubclassList;
- f_Subclasses->SetAt(hwnd, pList);
- }
- SubclassRec sdata;
- sdata.m_data = data;
- sdata.m_newproc = wndproc;
- sdata.m_oldproc = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_WNDPROC);
- sdata.m_suppressing = false;
- if (unsubclassSucceeded)
- sdata.m_succeededMsg = *unsubclassSucceeded;
- else
- sdata.m_succeededMsg.msg = 0;
- if (unsubclassFailed)
- sdata.m_failedMsg = *unsubclassFailed;
- else
- sdata.m_failedMsg.msg = 0;
- SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)wndproc);
- pList->AddHead(sdata);
- return true;
-}
-
-bool UnSubclass(WNDPROC id, HWND hwnd)
-{
- ASSERT(IsWindow(hwnd));
- // cross-thread window usage is not kosher ?
- ASSERT(GetCurrentThreadId() == GetWindowThreadProcessId(hwnd, 0));
- SubclassList *pList = 0;
- if (!f_Subclasses || !f_Subclasses->Lookup(hwnd, pList))
- // We've not subclassed this hwnd!
- return false;
- if (!pList->GetCount())
- // internal error
- return false;
- POSITION pos = pList->GetHeadPosition();
- SubclassRec srec = pList->GetNext(pos);
- if (srec.m_newproc == id)
- { // we're the latest subclass
- WNDPROC curproc = (WNDPROC) GetWindowLongPtr(hwnd, GWLP_WNDPROC);
- if (id != curproc)
- // We're not the current wndproc, so we can't safely unhook
- return false;
- ASSERT(srec.m_oldproc); // internal error
- SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)srec.m_oldproc);
- pList->RemoveHead();
- // fall thru to garbage collect list
- }
- else
- { // we're not the latest, but try to unhook anyway (may be ok)
- bool found=false;
- SubclassRec sprevrec = srec;
- for ( ; pos; pList->GetNext(pos), sprevrec=srec)
- {
- srec = pList->GetAt(pos);
- if (srec.m_newproc == id)
- {
- found=true;
- break;
- }
- }
- if (!found)
- // We've not subclassed with this wndproc (id) (or its been unsubclassed already)
- return false;
- if (sprevrec.m_oldproc != id)
- // Foreign subclass has intervened - we can't unhook
- return false;
- sprevrec.m_oldproc = srec.m_oldproc;
- pList->RemoveAt(pos);
- // fall thru to garbage collect list
- }
- // garbage collect
- if (!pList->GetCount())
- {
- f_Subclasses->RemoveKey(hwnd);
- delete pList;
- if (!f_Subclasses->GetCount())
- {
- delete f_Subclasses;
- f_Subclasses = 0;
- }
- }
- return true;
-}
-
-static SubclassRec * FindSubclass(WNDPROC id, HWND hwnd)
-{
- SubclassList *pList = 0;
- if (!f_Subclasses || !f_Subclasses->Lookup(hwnd, pList))
- // We've not subclassed this hwnd!
- return 0;
- for (POSITION pos = pList->GetHeadPosition(); pos; pList->GetNext(pos))
- {
- SubclassRec & srec = pList->GetAt(pos);
- if (srec.m_newproc == id)
- return &srec;
- }
- // We couldn't find our subclass of this hwnd
- return 0;
-}
-
-LRESULT CallOldProc(WNDPROC id, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
-{
- SubclassRec * psrec = FindSubclass(id, hwnd);
- if (!psrec) return 0;
- WNDPROC oldproc = psrec->m_oldproc; // psrec may get destroyed by the UnSubclass
- if (msg == WM_DESTROY || msg == WM_NCDESTROY)
- {
- Msg smsg = psrec->m_succeededMsg;
- bool succeeded = UnSubclass(id, hwnd);
- // if UnSubclass succeeds, psrec will be deleted
- if (succeeded)
- psrec = 0;
- if (!psrec && smsg.msg)
- {
- // succeeded, inform client
- CallWindowProc(id, hwnd, smsg.msg, smsg.wparam, smsg.lparam);
- }
- if (psrec && (msg == WM_NCDESTROY) && psrec->m_failedMsg.msg)
- {
- // failed our last chance, inform client
- Msg & fmsg = psrec->m_failedMsg;
- psrec->m_suppressing = true;
- CallWindowProc(id, hwnd, fmsg.msg, fmsg.wparam, fmsg.lparam);
- psrec->m_suppressing = false;
- }
- }
- // we don't forward the failed message
- // (the succeeded message will never get here, as it was sent after unsubclassed)
- if (psrec && psrec->m_suppressing)
- {
- const Msg & tmsg = psrec->m_failedMsg;
- if (tmsg.msg == msg && tmsg.wparam == wParam && tmsg.lparam == lParam)
- return 0;
- }
-
- return CallWindowProc(oldproc, hwnd, msg, wParam, lParam);
-}
-
-void * GetData(WNDPROC id, HWND hwnd)
-{
- SubclassRec * psrec = FindSubclass(id, hwnd);
- if (!psrec) return 0;
- return psrec->m_data;
-}
-
-
-
-
-} // namespace
+++ /dev/null
-/*!
- \file CSubclass.h
- \author Perry Rapp, Creator, 1998-2003
- \date Created: 1998
- \date Edited: 2001/12/12 PR
-
- \brief Subclass library - functions to subclass any window proc
-
-
- Multiple subclasses of a given window proc are allowed, as long as each is a different
- subclass window proc. A second subclass attempt with same window proc will fail --
- Subclass(..) will return false.
-
- Client may optionally specify unsubclass messages, if client wants to be notified
- after the subclass has succeeded or failed.
-*/
-/* The MIT License
-Copyright (c) 2001 Perry Rapp
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-#pragma once
-
-namespace prdlg {
-
-//! post-subclass message (CallOldProc does not forward these)
-// note that if another subclass removes ours violently, these will not get sent
-struct Msg
-{
- UINT msg; // must be non-zero to be used
- WPARAM wparam;
- LPARAM lparam;
-};
-
- //! Client calls Subclass(..) to install new window proc
-bool Subclass(WNDPROC wndproc, HWND hwnd, void * data
- , Msg * unsubclassSucceeded = NULL, Msg * unsubclassFailed = NULL);
-
- //! Client calls UnSubclass(..) to remove existing window proc subclass
- // this does NOT trigger post-subclass messages
-bool UnSubclass(WNDPROC id, HWND hwnd);
-
- //! Client must call CallOldProc(..) at end of subclassing proc
-LRESULT CallOldProc(WNDPROC id, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
-
- //! Client calls GetData(..) to retrieve data pointer passed in its Subclass(..) call
-void * GetData(WNDPROC id, HWND hwnd);
-
-
-} // namespace
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='UnicodeDebug|x64'">NotUsing</PrecompiledHeader>\r
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug Unicode + Code Analysis|x64'">NotUsing</PrecompiledHeader>\r
</ClCompile>\r
- <ClCompile Include="Common\CSubclass.cpp">\r
- </ClCompile>\r
<ClCompile Include="DropHandler.cpp">\r
</ClCompile>\r
<ClCompile Include="ImgMergeFrm.cpp" />\r
<ClInclude Include="ConflictFileParser.h" />\r
<ClInclude Include="Common\coretools.h" />\r
<ClInclude Include="Common\coretypes.h" />\r
- <ClInclude Include="Common\CSubclass.h" />\r
<ClInclude Include="Constants.h" />\r
<ClInclude Include="HexMergeView.h" />\r
<ClInclude Include="DropHandler.h" />\r
<ClCompile Include="Common\Bitmap.cpp">\r
<Filter>MFCGui\Common</Filter>\r
</ClCompile>\r
- <ClCompile Include="Common\CSubclass.cpp">\r
- <Filter>MFCGui\Common</Filter>\r
- </ClCompile>\r
<ClCompile Include="Common\ShellContextMenu.cpp">\r
<Filter>MFCGui\Common</Filter>\r
</ClCompile>\r
<ClInclude Include="OptionsPanel.h">\r
<Filter>MFCGui\Header Files</Filter>\r
</ClInclude>\r
- <ClInclude Include="Common\CSubclass.h">\r
- <Filter>MFCGui\Common</Filter>\r
- </ClInclude>\r
<ClInclude Include="Common\Bitmap.h">\r
<Filter>MFCGui\Common</Filter>\r
</ClInclude>\r