LRESULT CALLBACK Interpreter::CbtFilterHook(int code, WPARAM wParam, LPARAM lParam) { // Looking for HCBT_CREATEWND, just pass others on... if (code == HCBT_CREATEWND) { //ASSERT(lParam != NULL); //LPCREATESTRUCT lpcs = ((LPCBT_CREATEWND)lParam)->lpcs; //ASSERT(lpcs != NULL); OTE* underConstruction = m_oteUnderConstruction; if (!underConstruction->isNil()) { // Nil this out as soon as possible m_oteUnderConstruction = Pointers.Nil; underConstruction->countDown(); ASSERT(wParam != NULL); // should be non-NULL HWND // set m_bDlgCreate to TRUE if it is a dialog box // (this controls what kind of subclassing is done later) //pThreadState->m_bDlgCreate = (lpcs->lpszClass == WC_DIALOG); // Pass to Smalltalk for subclassing (catch unwind failures so not thrown out) subclassWindow(underConstruction, HWND(wParam)); } } return ::CallNextHookEx(hHookOldCbtFilter, code, wParam, lParam); }
BOOL __fastcall Interpreter::primitiveHookWindowCreate() { Oop argPointer = stackTop(); OTE* underConstruction = m_oteUnderConstruction; OTE* receiverPointer = reinterpret_cast<OTE*>(stackValue(1)); if (!underConstruction->isNil() && underConstruction != receiverPointer) { // Hooked by another window - fail the primitive return primitiveFailureWith(1, underConstruction); } if (argPointer == Oop(Pointers.True)) { // Hooking if (underConstruction != receiverPointer) { ASSERT(underConstruction->isNil()); m_oteUnderConstruction= receiverPointer; receiverPointer->countUp(); } } else { if (argPointer == Oop(Pointers.False)) { // Unhooking if (underConstruction == receiverPointer) { tracelock lock(TRACESTREAM); TRACESTREAM << "WARNING: Unhooking create for " << hex << underConstruction << " before HCBT_CREATEWND" << endl; ObjectMemory::nilOutPointer(m_oteUnderConstruction); } else ASSERT(underConstruction->isNil()); } else return primitiveFailureWith(0, argPointer); // Invalid argument } popStack(); return TRUE; }