Onega's profileOnegaBlogListsNetwork Tools Help

Blog


    July 02

    Programtically close child console process

    PostThreadMessage(process_info.dwThreadId, WM_QUIT, 0 ,0); does not work; I have to use CREATE_NEW_CONSOLE flag when creating the child process, so GenerateConsoleCtrlEvent does not work either. Console HWND can be found via EnumWindows API, then parent process invoke PostMessage(console_window, WM_CLOSE, 0, 0); or PostMessage(console_window, WM_SYSCOMMAND, SC_CLOSE, 0); child process will receive CTRL_CLOSE_EVENT, so child process can register CtrlHandler via SetConsoleCtrlHandler to close itself gracefully.If child process does not terminate within certain time, windows will prompt up “not respond” window, but child process can still exit when it finished its execution, or parent process can also invoke TerminateProcess to kill child process.

    June 24

    Build wxWidgets 2.8.10 with OpenGL via VC++ 2008

    modify wxWidgets-2.8.10\include\wx\setup_inc.h and
    wxWidgets-2.8.10\include\wx\msw\setup.h to enable wxUSE_GLCANVAS      
    #define wxUSE_GLCANVAS       1

    start VC++ command window and run following command:

    D:\opensource\wxWidgets-2.8.10\build\msw>nmake -f makefile.vc MONOLITHIC=0 SHARED=0 BUILD=release USE_OPENGL=1 USE_ODBC=1 UNICODE=1

    D:\opensource\wxWidgets-2.8.10\build\msw>nmake -f makefile.vc MONOLITHIC=0 SHARED=0 BUILD=debug USE_OPENGL=1 USE_ODBC=1 UNICODE=1

    February 21

    wxCommandEventHandler and Loki::PimplOf

    For a dialog class T derived from wxDialog and also inherited Loki::PimplOf<T>::Owner, it is still possible to hide the implementation of wxCommandEventHandler, just inherit the Loki::ImplOf<T> from wxEvtHandler like the following:

    class T: public wxDialog, private Loki::PimplOf<T>::Owner

    {

    }

    template <> struct Loki::ImplOf<T> : public wxEvtHandler

    {

    void OnButtonClicked(wxCommandEvent& wxevent);

    wxButton *mybutton;

    }

    typedef Loki::ImplOf<T> TPimpl;

    mybutton->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
        wxCommandEventHandler( TPimpl::OnButtonClicked), NULL, this);

    The trap is that member function pointer cast may change size in multiple inheritance case.

    Reference: Pointers to member functions are very strange animal

    TN016: Using C++ Multiple Inheritance with MFC

    October 17

    build wxWidgets 2.8.9 via VC++ 2008

    4 commands are needed in order to build multibyte/unicde and debug/release combinations.

    D:\src\wxWidgets-2.8.9\build\msw>nmake -f makefile.vc MONOLITHIC=1 SHARED=0 CFG=vc90 BUILD=debug USE_OPENGL=1 USE_ODBC=1 UNICODE=0

    D:\src\wxWidgets-2.8.9\build\msw>nmake -f makefile.vc MONOLITHIC=1 SHARED=0 CFG=vc90 BUILD=release USE_OPENGL=1 USE_ODBC=1 UNICODE=0

    D:\src\wxWidgets-2.8.9\build\msw>nmake -f makefile.vc MONOLITHIC=1 SHARED=0 CFG=vc90 BUILD=debug USE_OPENGL=1 USE_ODBC=1 UNICODE=1

    D:\src\wxWidgets-2.8.9\build\msw>nmake -f makefile.vc MONOLITHIC=1 SHARED=0 CFG=vc90 BUILD=release USE_OPENGL=1 USE_ODBC=1 UNICODE=1

    September 03

    wxWidgets-2.8.8 under Cygwin

    /cygdrive/d/src/wxWidgets-2.8.8/cygwin-rel
    $ ../configure --with-msw --disable-shared --without-subdirs --enable-monolithic --disable-debug CXXFLAGS="-mthreads" --build=i686-pc-cygwin
    /cygdrive/d/src/wxWidgets-2.8.8/cygwin-dbg
    $ ../configure --with-msw --enable-debug --enable-debug_gdb --disable-shared --without-subdirs --enable-monolithic CXXFLAGS="-mthreads" --build=i686-pc-mingw32

    May 13

    RegisterHotKey in wxWidgets

    Register hotkey via main window, not child window.

    Some keys do not work. In one case RegisterHotKey(CapturePage::hotkey_id, wxMOD_CONTROL, '8'); worked but "F12" does not work.

    EVT_HOTKEY(CapturePage::hotkey_id, PathUtilDlg::OnHotkey)

    March 31

    _open_osfhandle failed to open STD_OUTPUT_HANDLE

    _open_osfhandle always returns error when passing GetStdHandle(STD_OUTPUT_HANDLE) to it. However, STD_ERROR_HANDLE works fine.

    full code snippet:

    HANDLE output_handle = GetStdHandle(STD_OUTPUT_HANDLE);
    if (output_handle==INVALID_HANDLE_VALUE)
    {
        std::stringstream ss;
        ss << "GetStdHandle return " << GetLastError();
        OutputDebugString(ss.str().c_str());
    }
    else
    {
        std::cout.sync_with_stdio(true);
        int m_nCRTOut= _open_osfhandle( (intptr_t)output_handle, 0 );
        if (m_nCRTOut==-1)
        {
            std::stringstream ss;
            ss << "_open_osfhandle(" <<(int) output_handle << ") return " << errno << ", "
                << strerror( errno);
            OutputDebugString(ss.str().c_str()); //  _open_osfhandle(7) return 9, Bad file descriptor
        }
        else
        {
            FILE* m_fpCRTOut = _fdopen( m_nCRTOut, "w" );
            if (!m_fpCRTOut)
            {
                std::stringstream ss;
                ss << "_fdopen(" <<(int) m_nCRTOut << ") return " << errno << ", "
                    << strerror( errno);
                OutputDebugString(ss.str().c_str());

            }
            else
            {
                *stdout = *m_fpCRTOut;
                setvbuf( stdout, NULL, _IONBF, 0 );
            }
        }

    }
    std::cout.clear();

    Btw, a VK_RETURN key event needs to be programmatically fired in order to detach from console.

    if (m_attach_console)
    {
        FreeConsole();
        m_attach_console = FALSE;
         //simulate return pressing
        INPUT input;
        memset(&input,0,sizeof(input));
        input.type=INPUT_KEYBOARD;
        input.ki.wVk=VK_RETURN;
        SendInput(1,&input,sizeof(input));
        input.ki.dwFlags=KEYEVENTF_KEYUP;
        SendInput(1,&input,sizeof(input));
    }

    January 22

    Stingray2006V3 and VC++ 2008

    Stingray (2006V3) library does not support VC++ 2008 (http://www2.roguewave.com/support/matrices/matrix/support_matrix_stingray49.pdf), a kind of surprise to me. Usually a company would support VC++ 2008 in its early beta stage, but RogueWave didn't do that.

    Here are some tricks to make it compatible with VC++ 2008
    Add \RWSS2006v3\Lib\vc8\x86 to VC++ 2008 library path.
    Add \RWSS2006v3\RWUXTheme\Include to VC++ 2008 include path.
    \RWSS2006v3\include\SupportedPlatforms.h
    change line 22 to
    #if(_MSC_VER == 1400 || _MSC_VER == 1500) // for VC++ 2008 (9.0)

    \RWSS2006v3\Src\Foundation\image\mfc\jpeg\Jmemmgr.cpp line 1135
        #if(_MFC_VER <= 0x0900) // change from 0x0800 to 0x0900 for VC++ 2008

    Then many projects can be built in VC++ 2008 by converting VC++ 2003 or VC++ 2005 project files. For client projects, you may also need to put some library in "Ignore Specific Library" property of "Linker->Input" page, since auto link library name is different from build output in some cases. It is better to add VC++ 2008 entry in \RWSS2006V3\RWUXTheme\Include\RWUXTheme.h and change output name of RWUXTheme project.

    January 08

    building wxWidgets 2.8.7 with VC++ 9.0 Express Edition

    Command line:

    D:\wxWidgets-2.8.7\build\msw>nmake -f makefile.vc MONOLITHIC=1 SHARED=0 USE_EXCEPTION=1 USE_RTTI=1 RUNTIME_LIBS=dynamic CFG=vc9 BUILD=debug DEBUG_INFO=1 USE_HTML=1 USE_GUI=1

    D:\wxWidgets-2.8.7\build\msw>nmake -f makefile.vc MONOLITHIC=1 SHARED=0 USE_EXCEPTION=1 USE_RTTI=1 RUNTIME_LIBS=dynamic CFG=vc9 BUILD=release DEBUG_INFO=1 USE_HTML=1 USE_GUI=1

    Open D:\wxWidgets-2.8.7\samples\minimal\minimal.dsp project in VC++ 9.0 IDE, change its include path, library name and library path, another important step is to disable manefest files via menu:

    project->properties->Configuration Properties->Manifest Tool->Input and Output->Embed Manifest=No

    otherwise VC++ would report duplicated resource error, which is included in wx/msw/wx.rc.

    Update on 31 Jan. 2008: default flags are set in build\msw\config.vc, so I only need to overwrite desired values, so I use the following command -- nmake -f makefile.vc MONOLITHIC=1 SHARED=0 CFG=vc9 BUILD=release USE_OPENGL=1 USE_ODBC=1. The problem is that D:\wxWidgets-2.8.7\lib\vc_libvc9\mswd\wx\setup.h still contains

    #define wxUSE_GLCANVAS       0
    #define wxUSE_ODBC          0
    Then I modify D:\wxWidgets-2.8.7\include\wx\msw\setup.h since this file is copied to D:\wxWidgets-2.8.7\lib.

    building wxWidgets 2.8.7 with VC++ 9.0 Express Edition

    Command line:

    D:\wxWidgets-2.8.7\build\msw>nmake -f makefile.vc MONOLITHIC=1 SHARED=0 USE_EXCEPTION=1 USE_RTTI=1 RUNTIME_LIBS=dynamic CFG=vc9 BUILD=debug DEBUG_INFO=1 USE_HTML=1 USE_GUI=1

    Open D:\wxWidgets-2.8.7\samples\minimal\minimal.dsp project in VC++ 9.0 IDE, change its include path, library name and library path, another important step is to disable manefest files via menu:

    project->properties->Configuration Properties->Manifest Tool->Input and Output->Embed Manifest=No

    otherwise VC++ would report duplicated resource error.

    December 13

    wxWidgets 2.8.7 on FreeBSD 6.2

    First I have to enable executable right on configure

    ls -ol conf*

    chmod -v a=rwx configure

    ls -ol conf*

    #cd debuglib

    #../configure --with-gtk --enable-debug --enable-debug_gdb --disable-shared --without-subdirs --enable-monolithic

    December 12

    SWT should be built on top of wxWidgets

    When I encounter SWT, my immediate impression is that IBM is reinventing the wheel. It must save a lot of efforts if SWT was built on top of wxWidgets. In fact there is a hot discussion on this topic, although the opposite voice is also strong. Should SWT Build Ontop of wxWidgets?

    December 05

    wxWidgets-2.8.7 under Cygwin

    The following configuration worked with boost 1.34.1 (--toolset=gcc), but I got a huge size executable--34M, and the linking order is important, wx_mswd-2.8 must be the first (before uuid and comctl32) library to be linked.

    wxWidgets debug configuration:

    ../configure --with-msw --enable-debug --enable-debug_gdb --disable-shared --without-subdirs --enable-monolithic CXXFLAGS="-mthreads" --build=i686-pc-mingw32 --disable-precomp-headers

     

    Build log of my project:

    -------------- Build: Win32 Debug in wx1 ---------------

    Linking executable: D:\wxWidgets-2.8.7\cygwin-debug\lib\wx1.exe
    Reading specs from /usr/lib/gcc/i686-pc-cygwin/3.4.4/specs
    Configured with: /usr/build/package/orig/test.respin/gcc-3.4.4-3/configure --verbose --prefix=/usr --exec-prefix=/usr --sysconfdir=/etc --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --enable-languages=c,ada,c++,d,f77,pascal,java,objc --enable-nls --without-included-gettext --enable-version-specific-runtime-libs --without-x --enable-libgcj --disable-java-awt --with-system-zlib --enable-interpreter --disable-libgcj-debug --enable-threads=posix --enable-java-gc=boehm --disable-win32-registry --enable-sjlj-exceptions --enable-hash-synchronization --enable-libstdcxx-debug
    Thread model: posix
    gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
    /usr/lib/gcc/i686-pc-cygwin/3.4.4/collect2.exe --subsystem windows -Bdynamic --dll-search-prefix=cyg -o D:/wxWidgets-2.8.7/cygwin-debug/lib/wx1.exe /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../crt0.o -LD:/boost_1_34_1/stage/lib -LD:/wxWidgets-2.8.7/cygwin-debug/lib/ -LC:/cygwin/lib -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -L/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../.. cygwinDebug/CopyThread.o cygwinDebug/DeleteThread.o cygwinDebug/FindPage.o cygwinDebug/OBaseThread.o cygwinDebug/VerbosePage.o cygwinDebug/copypage.o cygwinDebug/mydlg.o cygwinDebug/ConfigPage.o --allow-multiple-definition -lwx_mswd-2.8 -lcomctl32 -lkernel32 -luser32 -lgdi32 -luuid -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lodbc32 -lodbccp32 -lshlwapi D:/boost_1_34_1/stage/lib/boost_filesystem-gcc34-mt-d-1_34_1.a -lexpat -lstdc++ -lgcc -lcygwin -lgdi32 -lcomdlg32 -luser32 -lkernel32 -ladvapi32 -lshell32 -lgcc
    Output size is 33.40 MB
    Process terminated with status 0 (0 minutes, 11 seconds)
    0 errors, 0 warnings

    wxWidgets Release configuration:

    ../configure --with-msw --disable-debug  --disable-shared --without-subdirs --enable-monolithic CXXFLAGS="-mthreads" --build=i686-pc-cygwin --without-libtiff --without-libpng --without-libjpeg --without-xpm --without-regex

    (Partial) Build log of wxWidgets:

    /cygdrive/d/wxWidgets-2.8.7/cygwin-relstatic/bk-deps g++ -c -o monolib_xml.o  -D
    __WXMSW__            -DwxUSE_BASE=1 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILES -I/cyg
    drive/d/wxWidgets-2.8.7/cygwin-relstatic/lib/wx/include/msw-ansi-release-static-
    2.8 -I../include -Wall -Wundef -Wno-ctor-dtor-privacy -O2 -fno-strict-aliasing -
    mthreads ../src/xml/xml.cpp

    ar rcu /cygdrive/d/wxWidgets-2.8.7/cygwin-relstatic/lib/libwx_msw-2.8.a monolib_
    appbase.o monolib_arcall.o (...)

    ranlib /cygdrive/d/wxWidgets-2.8.7/cygwin-relstatic/lib/libwx_msw-2.8.a

    Build log of my application:

    Compiling: ConfigPage.cpp
    Reading specs from /usr/lib/gcc/i686-pc-cygwin/3.4.4/specs
    Configured with: /usr/build/package/orig/test.respin/gcc-3.4.4-3/configure --verbose --prefix=/usr --exec-prefix=/usr --sysconfdir=/etc --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --enable-languages=c,ada,c++,d,f77,pascal,java,objc --enable-nls --without-included-gettext --enable-version-specific-runtime-libs --without-x --enable-libgcj --disable-java-awt --with-system-zlib --enable-interpreter --disable-libgcj-debug --enable-threads=posix --enable-java-gc=boehm --disable-win32-registry --enable-sjlj-exceptions --enable-hash-synchronization --enable-libstdcxx-debug
    Thread model: posix
    gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
    /usr/lib/gcc/i686-pc-cygwin/3.4.4/cc1plus.exe -quiet -v -I../../wxWidgets-2.8.7/include -ID:/boost_1_34_1 -ID:/wxWidgets-2.8.7/cygwin-relstatic/lib/wx/include/msw-ansi-release-static-2.8 -IC:/cygwin/include -D__CYGWIN32__ -D__CYGWIN__ -Dunix -D__unix__ -D__unix -idirafter /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../include/w32api -idirafter /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/lib/../../include/w32api -DWIN32 -D_WINDOWS -D_MBCS -D__WXMSW__ D:/onega/wx1/ConfigPage.cpp -quiet -dumpbase ConfigPage.cpp -march=i686 -mthreads -auxbase-strip cygwinRelease/ConfigPage.o -g -Wno-ctor-dtor-privacy -version -o /cygdrive/c/DOCUME~1/ONEGA~1.ZHA/LOCALS~1/Temp/ccK8TPmb.s
    ignoring nonexistent directory "/usr/local/include"
    ignoring nonexistent directory "/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/include"
    ignoring duplicate directory "/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/lib/../../include/w32api"
    ignoring nonexistent directory "C:/cygwin/include"
    #include "..." search starts here:
    #include <...> search starts here:
    ../../wxWidgets-2.8.7/include
    D:/boost_1_34_1
    D:/wxWidgets-2.8.7/cygwin-relstatic/lib/wx/include/msw-ansi-release-static-2.8
    /usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++
    /usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/i686-pc-cygwin
    /usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/backward
    /usr/lib/gcc/i686-pc-cygwin/3.4.4/include
    /usr/include
    /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../include/w32api
    End of search list.
    GNU C++ version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125) (i686-pc-cygwin)
        compiled by GNU C version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125).
    GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
    /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../../i686-pc-cygwin/bin/as.exe -o cygwinRelease/ConfigPage.o /cygdrive/c/DOCUME~1/ONEGA~1.ZHA/LOCALS~1/Temp/ccK8TPmb.s
    Linking executable: D:\wxWidgets-2.8.7\cygwin-debugdll\lib\wx1.exe
    Reading specs from /usr/lib/gcc/i686-pc-cygwin/3.4.4/specs
    Configured with: /usr/build/package/orig/test.respin/gcc-3.4.4-3/configure --verbose --prefix=/usr --exec-prefix=/usr --sysconfdir=/etc --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --enable-languages=c,ada,c++,d,f77,pascal,java,objc --enable-nls --without-included-gettext --enable-version-specific-runtime-libs --without-x --enable-libgcj --disable-java-awt --with-system-zlib --enable-interpreter --disable-libgcj-debug --enable-threads=posix --enable-java-gc=boehm --disable-win32-registry --enable-sjlj-exceptions --enable-hash-synchronization --enable-libstdcxx-debug
    Thread model: posix
    gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
    /usr/lib/gcc/i686-pc-cygwin/3.4.4/collect2.exe --subsystem windows -Bdynamic --dll-search-prefix=cyg -o D:/wxWidgets-2.8.7/cygwin-debugdll/lib/wx1.exe /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../crt0.o -LD:/boost_1_34_1/stage/lib -LC:/cygwin/lib -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -L/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../.. cygwinRelease/CopyThread.o cygwinRelease/DeleteThread.o cygwinRelease/FindPage.o cygwinRelease/OBaseThread.o cygwinRelease/VerbosePage.o cygwinRelease/copypage.o cygwinRelease/mydlg.o cygwinRelease/ConfigPage.o --allow-multiple-definition D:/wxWidgets-2.8.7/cygwin-relstatic/lib/libwx_msw-2.8.a -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lodbccp32 -loleaut32 -lcomctl32 -lshlwapi -lkernel32 -luser32 -lgdi32 -lexpat -luuid -lole32 D:/boost_1_34_1/stage/lib/boost_filesystem-gcc34-mt-d-1_34_1.a -lstdc++ -lgcc -lcygwin -lgdi32 -lcomdlg32 -luser32 -lkernel32 -ladvapi32 -lshell32 -lgcc
    Output size is 10.31 MB
    Process terminated with status 0 (0 minutes, 44 seconds)
    0 errors, 4 warnings

     

    zlib package is required, although there is a "--with-zlib" option. Otherwise build will fail with the following error:

    /cygdrive/d/wxWidgets-2.8.7/cygwin-debugdll/bk-deps g++ -c -o monodll_fs_arc.o
    -D__WXMSW__            -DwxUSE_BASE=1 -DWXMAKINGDLL  -D_FILE_OFFSET_BITS=64 -D_L
    ARGE_FILES -D__WXDEBUG__ -I/cygdrive/d/wxWidgets-2.8.7/cygwin-debugdll/lib/wx/in
    clude/msw-ansi-debug-2.8 -I../include -Wall -Wundef -Wno-ctor-dtor-privacy -ggdb
    -O0 -mthreads ../src/common/fs_arc.cpp
    ../src/common/fs_arc.cpp:45: error: ISO C++ forbids declaration of `wxArchiveEnt
    ry' with no type
    ../src/common/fs_arc.cpp:45: error: expected `;' before '*' token
    ../src/common/fs_arc.cpp:45: error: ISO C++ forbids declaration of `wxArchiveEnt
    ry' with no type
    ../src/common/fs_arc.cpp:45: error: expected `;' before '*' token
    ../src/common/fs_arc.cpp:45: error: expected `,' or `...' before '&' token
    ../src/common/fs_arc.cpp:45: error: ISO C++ forbids declaration of `const_t2' wi
    th no type
    ../src/common/fs_arc.cpp:45: error: `t2' does not name a type

      Summary:

    DLL version (--enable-shared) of wxWidgets always got "0xC0000005" error on my application startup, while static library version (--disabled-shared) works for the same project on Windows XP SP2.

    October 16

    wxWidgets-2.8.6 and VC8 on Windows XP

    It seems that I have to enable USE_EXCEPTIONS when building wxWidgets via VC8 on Windows XP, otherwise the sample code(E:\opensource\wxWidgets-2.8.6\samples\except\except.dsp) got stack overflow problem.

    I also need to add a function to this sample project in order to fix the unresolved link error to wxAppConsole::HandleEvent().

    void MyApp::HandleEvent( wxEvtHandler *handler, wxEventFunction func, wxEvent& event ) const
    {
        (handler->*func)(event);
    }

    The following command works well:

    E:\opensource\wxWidgets-2.8.6\build\msw>nmake -f makefile.vc MONOLITHIC=1 SHARED
    =0 USE_EXCEPTIONS=1 USE_RTTI=1 RUNTIME_LIBS=dynamic CPPFLAGS="/Zc:wchar_t- /EHa" CFG=vc8 BUILD=debug DEBUG_INFO=1

    E:\opensource\wxWidgets-2.8.6\build\msw>nmake -f makefile.vc MONOLITHIC=1 SHARED
    =0 USE_EXCEPTIONS=1 USE_RTTI=1 RUNTIME_LIBS=dynamic CPPFLAGS="/Zc:wchar_t- /EHa" CFG=vc8 BUILD=release DEBUG_INFO=1

    The following build output leads to stack overflow problem:

    E:\opensource\wxWidgets-2.8.6\build\msw>nmake -f makefile.vc MONOLITHIC=1 SHARED
    =0 USE_EXCEPTIONS=0 USE_RTTI=1 RUNTIME_LIBS=dynamic CPPFLAGS="/Zc:wchar_t- /EHa"

    August 28

    sort wxGrid by clicking column header

    Here is a simple code snippet for sorting wxGrid on column header click
    event. I assume all values are string in order to demonstrate the
    concept for short. Enjoy it(www.fruitfruit.com).
    BEGIN_EVENT_TABLE(InvoicePage, wxPanel)
    EVT_GRID_LABEL_LEFT_CLICK(InvoicePage::OnGridEvent)
    END_EVENT_TABLE()
    void InvoicePage::OnGridEvent( wxGridEvent& event )
    {
    typedef std::list<wxString> StringList;
    typedef boost::shared_ptr<StringList> PtrStringList;
    // sort as string
    std::multimap<wxString, PtrStringList > sort_col;
    for (int i=0; i<m_grid->GetNumberRows(); i++)
    {
    PtrStringList a_row(new StringList);
    sort_col.insert(std::pair<wxString,
    PtrStringList>(m_grid->GetCellValue(i, event.GetCol()), a_row));
    for (int j=0; j<m_grid->GetNumberCols(); j++)
    {
    a_row->push_back(m_grid->GetCellValue(i,j));
    }
    }
    int current_row = 0;
    while(sort_col.size())
    {
    PtrStringList row_data = sort_col.begin()->second;
    sort_col.erase(sort_col.begin());
    for(int i=0; i<m_grid->GetNumberCols(); i++)
    {
    m_grid->SetCellValue(current_row, i, row_data->front());
    row_data->pop_front();
    }
    current_row++;
    }
    m_grid->SetSortCol(event.GetCol()); // it is a custom wxGrid for
    drawing sort indicator.
    m_grid->GetGridColLabelWindow()->Refresh(); // force repaint of
    column header.
    }




    paint column header of wxGrid

    When I want to draw sort indicator on column header of wxGrid, only
    wxPython example is found via google, but the sample is not the style I
    want. So the following code snippet is created. I also need to call
    m_grid->GetGridColLabelWindow()->Refresh(); for the event
    EVT_GRID_LABEL_LEFT_CLICK in order to trigger repaint of the column
    header window. Good luck(www.fruitfruit.com).
    class SortGrid :public wxGrid
    {
    public:
    SortGrid(wxWindow* parent, wxWindowID id, const wxPoint& pos =
    wxDefaultPosition, const wxSize& size = wxDefaultSize, long style =
    wxWANTS_CHARS, const wxString& name = wxPanelNameStr);
    void SetSortCol(int col);
    private:
    void OnPaintLabel(wxPaintEvent& evt);
    int m_sort_column;
    bool m_ascend;
    };


    SortGrid::SortGrid(wxWindow* parent, wxWindowID id, const wxPoint& pos,
    const wxSize& size, long style, const wxString& name)
    :wxGrid(parent, id, pos, size, style, name)
    {
    m_ascend = false;
    m_sort_column = -1;
    GetGridColLabelWindow()->Connect(wxEVT_PAINT,
    wxPaintEventHandler(SortGrid::OnPaintLabel), NULL, this);
    }

    void SortGrid::OnPaintLabel( wxPaintEvent& evt )
    {
    const int COL_COUNT = WXSIZEOF(INVOICE_COL_LABELS);
    wxWindow* w = GetGridColLabelWindow();
    wxString msg;
    msg.Printf("%s m_sort_column=%d, NumberCols = %d", __FUNCTION__,
    m_sort_column, GetNumberCols());
    OutputDebugString(msg);
    if (m_sort_column<0 || m_sort_column > COL_COUNT )
    {
    evt.Skip();
    return;
    }
    if (!w)
    {
    evt.Skip();
    return;
    }
    wxPaintDC dc(w);
    wxRect clientRect = w->GetClientRect();
    wxFont font = dc.GetFont();
    int x = 0, y = 0;
    int totColSize = 0;
    GetViewStart(&x, &y);
    int pixelsPerUnitX, pixelsPerUnitY;
    GetScrollPixelsPerUnit(&pixelsPerUnitX, &pixelsPerUnitY);
    totColSize = 0 - x * pixelsPerUnitX;
    wxBrush wheat(wxT("WHEAT"), wxTRANSPARENT);
    for (int col =0; col<COL_COUNT; col++)
    {
    dc.SetBrush(wheat);
    int colSize = GetColSize(col);
    wxRect rect(totColSize, 0, colSize, 32);
    rect.Deflate(1,1);
    dc.DrawRectangle(rect.x , rect.y,
    rect.width , rect.height);
    totColSize += colSize;
    if (col==m_sort_column)
    {
    font.SetWeight(wxBOLD);
    if (m_ascend)
    {
    dc.SetTextForeground(*wxRED);
    }
    else
    {
    dc.SetTextForeground(*wxGREEN);
    }
    }
    else
    {
    dc.SetTextForeground(*wxBLACK);
    font.SetWeight(wxNORMAL);
    }
    dc.SetFont(font);
    rect.Deflate(1,1);
    dc.DrawLabel(this->GetColLabelValue(col), rect);
    }
    }

    void SortGrid::SetSortCol( int col)
    {
    if (m_sort_column == col)
    {
    m_ascend = !m_ascend;
    }
    else
    {
    m_sort_column = col;
    }
    }


    August 01

    multiple inheritance cause problem in wxWidgets event handling

    I have a class derived from wxPanel and also implementing a custom
    interface. At first I wrote it in the following way:
    class CopyPage :public IPage, public wxPanel
    {
    ...
    DECLARE_EVENT_TABLE()
    };

    BEGIN_EVENT_TABLE(CopyPage, wxPanel)
    EVT_BUTTON(wxID_ANY, CopyPage::OnButton)
    END_EVENT_TABLE()

    There are several buttons in CopyPage. A strange behavior is observed
    that when I click on first button, nothing happens, when I click second
    button, first button is triggered.
    After I change the declaration of CopyPage, everything is fine.
    class CopyPage :public wxPanel, public IPage





    June 29

    Qt 4.3.0

    Downloaded Qt 4.3.0, but the open source edition does not support VC++.
    win32-msvc (commercial edition only)
    win32-msvc.net (commercial edition only)
    win32-msvc2005 (commercial edition only)

    Its layout organizer is a little bit different from wxWidgets and Java (IMHO it is weaker than wxWidgets.).

    Using Code::Blocks to create a Qt4 project, a link error is encountered:
    undefined reference to `__cpu_features_init'
    The fix is: update GNU GCC Compiler to latest version of MINGW from menu Settings->Compiler and debugger...

    To compile it via mingw, add E:\MinGW\bin to PATH, run the following command
    e:\qt\4.3.0\configure -platform win32-g++
    It is a big surprise that Qt does not support cygwin!
    June 24

    wxWidgets

    After building \wxWidgets-2.8.3\build\msw\wx.dsw via VC++ 6.0, it
    consumes 5.19G disk space.
    To use it, add the following include path:
    D:\apps\wxWidgets-2.8.4\include\msvc
    D:\apps\wxWidgets-2.8.4\include
    add the following library path:
    D:\apps\wxWidgets-2.8.4\lib\vc_lib

    wxWidgets is easy to use for people with java background. I found myself familiar to its wxGridBagSizer usage with no time, which is my favorite one when doing java GUI. IMHO it is better than MFC.

    The debug configuration of my wxWidgets project always reports a link error:
    wxmsw28d_core.lib(appcmn.obj) : error LNK2001: unresolved external symbol "protected: virtual class wxString __thiscall wxAppTraitsBase::GetAssertStackTrace(void)" (?GetAssertStackTrace@wxAppTraitsBase@@MAE?AVwxString@@XZ)
    Google does not help me on this. So I overcome it in this way:
    in one cpp file
    #include <wx/apptrait.h>
    #if wxUSE_STACKWALKER && defined( __WXDEBUG__ )
    // silly workaround for the link error with debug configuration:
    // \src\common\appbase.cpp
    wxString wxAppTraitsBase::GetAssertStackTrace()
    {
       return wxT("");
    }
    #endif

    To build static release library via VC8:
    I:\wxWidgets-2.8.4\build\msw>nmake -f makefile.vc MONOLITHIC=1 SHARED=0 USE_EXCEPTIONS=0 USE_RTTI=1 RUNTIME_LIBS=dynamic CPPFLAGS="/Zc:wchar_t- /EHa" BUILD=release DEBUG_INFO=1

    To build static debug libarary via VC8:
    I:\wxWidgets-2.8.4\build\msw>nmake -f makefile.vc MONOLITHIC=1 SHARED=0 USE_EXCEPTIONS=0 USE_RTTI=1 RUNTIME_LIBS=dynamic CPPFLAGS="/Zc:wchar_t- /EHa"