Donnerstag, 8. November 2012

ObjectStudio 8.4 ListView extensions

Some years ago I implemented some ListView extensions using WindowProc subclassing and primitives. While testing the new ObjectStudio Release 8.4.1 I found that registering our own WindowProc lead to crashes. I originally used the CHookWnd class, but because this class was marked obsolete by its author I had to find another way.

Using CWindowImpl I was now able to create a first working demo again.

Here is the primitive method which I use to register my own WindowProc for a ListView. It gets called from Smalltalk right after the ListView opens:

 BOOL LV_Init() {

     INIT_LOCAL_GVARS;
    OPTR oSelf;
    oSelf = PTOSn(0);

    // Get CPP handle of ListView form item
    OPTR oCppHandle = GetObjVar(oSelf,GetInstVarOffset(oSelf,SymbolHash((PSZ)_T("cppHandle"))));
    if (IsNil(oCppHandle)) return FALSE;

    // Check if handle is valid and get a reference to the MFC CListCtrl object
    if(ObjHandle(oCppHandle) == NULL) return FALSE;
    if(!AfxIsValidAddress((void*)ObjHandle(oCppHandle),sizeof(CListCtrl), true)) 
                 return FALSE;
    CListCtrl* m_pCtrl = (CListCtrl*)ObjHandle(oCppHandle);
    if(!m_pCtrl) return FALSE;


    HWND hwnd = m_pCtrl->GetSafeHwnd();
    if (hwnd == NULL) return FALSE;

   // New Code to Subclass the WindowProc instead of CHookWnd
    CMyListViewEx *myListViewEx = new CMyListViewEx();
    BOOL result = myListViewEx->SubclassWindow(hwnd);


    return result;
}

And this is the extension demo class, printing out middle mouse buttons down events to the transcript:

class CMyListViewEx : public CWindowImpl<CMyListViewEx,CListCtrl>
{
public:

    BEGIN_MSG_MAP(
CMyListViewEx)
        MESSAGE_HANDLER(WM_MBUTTONDOWN, OnMButtonDown)
    END_MSG_MAP()

    LRESULT OnMButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) {

       INIT_LOCAL_GVARS;
       Out(_T("MBUTTONDOWN %i %i %i"), uMsg, wParam, lParam);

       bHandled = TRUE;
       return TRUE;
    }

   
CMyListViewEx(void);
    ~
CMyListViewEx(void);
   
    void OnFinalMessage(HWND hWnd) {
        UnsubclassWindow(TRUE);
        delete this;
    }
}


If we ever finish porting from ObjectStudio 7 to 8 I may contribute our extensions to the Cincom public Store repository.

See also:

Keine Kommentare: