Example #1
0
static ULONG_PTR wxPySetActivationContext()
{

    OSVERSIONINFO info;
    wxZeroMemory(info);
    info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    GetVersionEx(&info);
    if (info.dwMajorVersion < 5)
        return 0;

    ULONG_PTR cookie = 0;
    HANDLE h;
    ACTCTX actctx;
    TCHAR modulename[MAX_PATH];

    GetModuleFileName(wxGetInstance(), modulename, MAX_PATH);
    wxZeroMemory(actctx);
    actctx.cbSize = sizeof(actctx);
    actctx.lpSource = modulename;
    actctx.lpResourceName = MAKEINTRESOURCE(2);
    actctx.hModule = wxGetInstance();
    actctx.dwFlags = ACTCTX_FLAG_HMODULE_VALID | ACTCTX_FLAG_RESOURCE_NAME_VALID;

    h = CreateActCtx(&actctx);
    if (h == INVALID_HANDLE_VALUE) {
        wxLogLastError(wxT("CreateActCtx"));
        return 0;
    }

    if (! ActivateActCtx(h, &cookie))
        wxLogLastError(wxT("ActivateActCtx"));

    return cookie;
}
Example #2
0
wxOperatingSystemId wxGetOsVersion(int *verMaj, int *verMin)
{
    OSVERSIONINFO info;
    wxZeroMemory(info);

    info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    if ( ::GetVersionEx(&info) )
    {
        if (verMaj) *verMaj = info.dwMajorVersion;
        if (verMin) *verMin = info.dwMinorVersion;
    }

#if defined( __WXWINCE__ )
    return wxOS_WINDOWS_CE;
#elif defined( __WXMICROWIN__ )
    return wxOS_WINDOWS_MICRO;
#else
    switch ( info.dwPlatformId )
    {
    case VER_PLATFORM_WIN32_NT:
        return wxOS_WINDOWS_NT;

    case VER_PLATFORM_WIN32_WINDOWS:
        return wxOS_WINDOWS_9X;
    }

    return wxOS_UNKNOWN;
#endif
}
Example #3
0
void wxStackFrame::OnGetName()
{
    if ( m_hasName )
        return;

    m_hasName = true;

    // get the name of the function for this stack frame entry
    static const size_t MAX_NAME_LEN = 1024;
    BYTE symbolBuffer[sizeof(SYMBOL_INFO) + MAX_NAME_LEN];
    wxZeroMemory(symbolBuffer);

    PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)symbolBuffer;
    pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
    pSymbol->MaxNameLen = MAX_NAME_LEN;

    DWORD64 symDisplacement = 0;
    if ( !wxDbgHelpDLL::SymFromAddr
                        (
                            ::GetCurrentProcess(),
                            GetSymAddr(),
                            &symDisplacement,
                            pSymbol
                        ) )
    {
        wxDbgHelpDLL::LogError(_T("SymFromAddr"));
        return;
    }

    m_name = wxString::FromAscii(pSymbol->Name);
    m_offset = symDisplacement;
}
Example #4
0
void wxTopLevelWindowMSW::Init()
{
    m_iconized =
    m_maximizeOnShow = false;

    // Data to save/restore when calling ShowFullScreen
    m_fsStyle = 0;
    m_fsOldWindowStyle = 0;
    m_fsIsMaximized = false;
    m_fsIsShowing = false;

    m_winLastFocused = NULL;

#if defined(__SMARTPHONE__) && defined(__WXWINCE__)
    m_MenuBarHWND = 0;
#endif

#if defined(__SMARTPHONE__) || defined(__POCKETPC__)
    SHACTIVATEINFO* info = new SHACTIVATEINFO;
    wxZeroMemory(*info);
    info->cbSize = sizeof(SHACTIVATEINFO);

    m_activateInfo = (void*) info;
#endif

    m_menuSystem = NULL;
}
Example #5
0
void wxStackFrame::OnGetParam()
{
    // use SymSetContext to get just the locals/params for this frame
    IMAGEHLP_STACK_FRAME imagehlpStackFrame;
    wxZeroMemory(imagehlpStackFrame);
    imagehlpStackFrame.InstructionOffset = GetSymAddr();
    if ( !wxDbgHelpDLL::SymSetContext
                        (
                            ::GetCurrentProcess(),
                            &imagehlpStackFrame,
                            0           // unused
                        ) )
    {
        // for symbols from kernel DLL we might not have access to their
        // address, this is not a real error
        if ( ::GetLastError() != ERROR_INVALID_ADDRESS )
        {
            wxDbgHelpDLL::LogError(_T("SymSetContext"));
        }

        return;
    }

    if ( !wxDbgHelpDLL::SymEnumSymbols
                        (
                            ::GetCurrentProcess(),
                            NULL,               // DLL base: use current context
                            NULL,               // no mask, get all symbols
                            EnumSymbolsProc,    // callback
                            this                // data to pass to it
                        ) )
    {
        wxDbgHelpDLL::LogError(_T("SymEnumSymbols"));
    }
}
Example #6
0
/* static */
HWND wxTLWHiddenParentModule::GetHWND()
{
    if ( !ms_hwnd )
    {
        if ( !ms_className )
        {
            static const wxChar *HIDDEN_PARENT_CLASS = wxT("wxTLWHiddenParent");

            WNDCLASS wndclass;
            wxZeroMemory(wndclass);

            wndclass.lpfnWndProc   = DefWindowProc;
            wndclass.hInstance     = wxGetInstance();
            wndclass.lpszClassName = HIDDEN_PARENT_CLASS;

            if ( !::RegisterClass(&wndclass) )
            {
                wxLogLastError(wxT("RegisterClass(\"wxTLWHiddenParent\")"));
            }
            else
            {
                ms_className = HIDDEN_PARENT_CLASS;
            }
        }

        ms_hwnd = ::CreateWindow(ms_className, wxEmptyString, 0, 0, 0, 0, 0, NULL,
                                 (HMENU)NULL, wxGetInstance(), NULL);
        if ( !ms_hwnd )
        {
            wxLogLastError(wxT("CreateWindow(hidden TLW parent)"));
        }
    }

    return ms_hwnd;
}
Example #7
0
int wxCheckListBox::DoInsertItems(const wxArrayStringsAdapter & items,
                                  unsigned int pos,
                                  void **clientData, wxClientDataType type)
{
    const unsigned int count = items.GetCount();

    ListView_SetItemCount( GetHwnd(), GetCount() + count );

    int n = wxNOT_FOUND;

    for( unsigned int i = 0; i < count; i++ )
    {
        LVITEM newItem;
        wxZeroMemory(newItem);
        newItem.iItem = pos + i;
        n = ListView_InsertItem( (HWND)GetHWND(), & newItem );
        wxCHECK_MSG( n != -1, -1, wxT("Item not added") );
        SetString( n, items[i] );
        m_itemsClientData.Insert(NULL, n);

        AssignNewItemClientData(n, clientData, i, type);
    }

    return n;
}
Example #8
0
/* static */
const wxChar *wxApp::GetRegisteredClassName(const wxChar *name,
                                            int bgBrushCol,
                                            int extraStyles)
{
    const size_t count = gs_regClassesInfo.size();
#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
    for ( size_t n = 0; n < count; n++ )
    {
        if ( gs_regClassesInfo[n].regname == name )
            return gs_regClassesInfo[n].regname.c_str();
    }

    // we need to register this class
    WNDCLASS wndclass;
    wxZeroMemory(wndclass);

    wndclass.lpfnWndProc   = (WNDPROC)wxWndProc;
    wndclass.hInstance     = wxGetInstance();
    wndclass.hCursor       = ::LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH)wxUIntToPtr(bgBrushCol + 1);
    wndclass.style         = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | extraStyles;


    ClassRegInfo regClass(name);
    wndclass.lpszClassName = regClass.regname.t_str();
    if ( !::RegisterClass(&wndclass) )
    {
        wxLogLastError(wxString::Format(wxT("RegisterClass(%s)"),
                       regClass.regname));
        return NULL;
    }

    wndclass.style &= ~(CS_HREDRAW | CS_VREDRAW);
    wndclass.lpszClassName = regClass.regnameNR.t_str();
    if ( !::RegisterClass(&wndclass) )
    {
        wxLogLastError(wxString::Format(wxT("RegisterClass(%s)"),
                       regClass.regname));
        ::UnregisterClass(regClass.regname.c_str(), wxGetInstance());
        return NULL;
    }

    gs_regClassesInfo.push_back(regClass);

    // take care to return the pointer which will remain valid after the
    // function returns (it could be invalidated later if new elements are
    // added to the vector and it's reallocated but this shouldn't matter as
    // this pointer should be used right now, not stored)
    return gs_regClassesInfo.back().regname.t_str();
}
Example #9
0
/* static */
size_t wxDIB::ConvertFromBitmap(BITMAPINFO *pbi, HBITMAP hbmp)
{
    wxASSERT_MSG( hbmp, wxT("invalid bmp can't be converted to DIB") );

    // prepare all the info we need
    BITMAP bm;
    if ( !::GetObject(hbmp, sizeof(bm), &bm) )
    {
        wxLogLastError(wxT("GetObject(bitmap)"));

        return 0;
    }

    // we need a BITMAPINFO anyhow and if we're not given a pointer to it we
    // use this one
    BITMAPINFO bi2;

    const bool wantSizeOnly = pbi == NULL;
    if ( wantSizeOnly )
        pbi = &bi2;

    // just for convenience
    const int h = bm.bmHeight;

    // init the header
    BITMAPINFOHEADER& bi = pbi->bmiHeader;
    wxZeroMemory(bi);
    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = bm.bmWidth;
    bi.biHeight = h;
    bi.biPlanes = 1;
    bi.biBitCount = bm.bmBitsPixel;

    // memory we need for BITMAPINFO only
    DWORD dwLen = bi.biSize + GetNumberOfColours(bm.bmBitsPixel) * sizeof(RGBQUAD);

    // get either just the image size or the image bits
    if ( !::GetDIBits
            (
                ScreenHDC(),                        // the DC to use
                hbmp,                               // the source DDB
                0,                                  // first scan line
                h,                                  // number of lines to copy
                wantSizeOnly ? NULL                 // pointer to the buffer or
                             : (char *)pbi + dwLen, // NULL if we don't have it
                pbi,                                // bitmap header
                DIB_RGB_COLORS                      // or DIB_PAL_COLORS
            ) )
    {
        wxLogLastError(wxT("GetDIBits()"));

        return 0;
    }

    // return the total size
    return dwLen + bi.biSizeImage;
}
Example #10
0
void wxMenuBar::SetLabelTop(size_t pos, const wxString& label)
{
    wxCHECK_RET( pos < GetMenuCount(), wxT("invalid menu index") );

    m_titles[pos] = label;

    if ( !IsAttached() )
    {
        return;
    }
    //else: have to modify the existing menu

    int mswpos = MSWPositionForWxMenu(GetMenu(pos),pos);

    UINT id;
    UINT flagsOld = ::GetMenuState((HMENU)m_hMenu, mswpos, MF_BYPOSITION);
    if ( flagsOld == 0xFFFFFFFF )
    {
        wxLogLastError(wxT("GetMenuState"));

        return;
    }

    if ( flagsOld & MF_POPUP )
    {
        // HIBYTE contains the number of items in the submenu in this case
        flagsOld &= 0xff;
        id = (UINT)::GetSubMenu((HMENU)m_hMenu, mswpos);
    }
    else
    {
        id = pos;
    }

#ifdef __WXWINCE__
    MENUITEMINFO info;
    wxZeroMemory(info);
    info.cbSize = sizeof(info);
    info.fMask = MIIM_TYPE;
    info.fType = MFT_STRING;
    info.cch = label.Length();
    info.dwTypeData = (LPTSTR) label.c_str();
    if ( !SetMenuItemInfo(GetHmenu(), id, TRUE, & info) )
    {
        wxLogLastError(wxT("SetMenuItemInfo"));
    }

#else
    if ( ::ModifyMenu(GetHmenu(), mswpos, MF_BYPOSITION | MF_STRING | flagsOld,
        id, label) == (int)0xFFFFFFFF )
    {
        wxLogLastError(wxT("ModifyMenu"));
    }
#endif

    Refresh();
}
Example #11
0
// save system data
HRESULT
wxIDataObject::SaveSystemData(FORMATETC *pformatetc,
                                 STGMEDIUM *pmedium,
                                 BOOL fRelease)
{
    if ( pformatetc == NULL || pmedium == NULL )
        return E_INVALIDARG;

    // remove entry if already available
    for ( SystemData::iterator it = m_systemData.begin();
          it != m_systemData.end();
          ++it )
    {
        if ( pformatetc->tymed & (*it)->pformatetc->tymed &&
             pformatetc->dwAspect == (*it)->pformatetc->dwAspect &&
             pformatetc->cfFormat == (*it)->pformatetc->cfFormat )
        {
            delete (*it);
            m_systemData.erase(it);
            break;
        }
    }

    // create new format/medium
    FORMATETC* pnewformatEtc = new FORMATETC;
    STGMEDIUM* pnewmedium = new STGMEDIUM;

    wxZeroMemory(*pnewformatEtc);
    wxZeroMemory(*pnewmedium);

    // copy format
    *pnewformatEtc = *pformatetc;

    // copy or take ownerschip of medium
    if ( fRelease )
        *pnewmedium = *pmedium;
    else
        wxCopyStgMedium(pmedium, pnewmedium);

    // save entry
    m_systemData.push_back(new SystemDataEntry(pnewformatEtc, pnewmedium));

    return S_OK;
}
Example #12
0
wxToolkitInfo& wxAppTraits::GetToolkitInfo()
{
    // cache the version info, it's not going to change
    //
    // NB: this is MT-safe, we may use these static vars from different threads
    //     but as they always have the same value it doesn't matter
    static int s_ver = -1,
               s_major = -1,
               s_minor = -1;

    if ( s_ver == -1 )
    {
        OSVERSIONINFO info;
        wxZeroMemory(info);

        s_ver = wxWINDOWS;
        info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
        if ( ::GetVersionEx(&info) )
        {
            s_major = info.dwMajorVersion;
            s_minor = info.dwMinorVersion;

#ifdef __SMARTPHONE__
            s_ver = wxWINDOWS_SMARTPHONE;
#elif defined(__POCKETPC__)
            s_ver = wxWINDOWS_POCKETPC;
#else
            switch ( info.dwPlatformId )
            {
                case VER_PLATFORM_WIN32s:
                    s_ver = wxWIN32S;
                    break;

                case VER_PLATFORM_WIN32_WINDOWS:
                    s_ver = wxWIN95;
                    break;

                case VER_PLATFORM_WIN32_NT:
                    s_ver = wxWINDOWS_NT;
                    break;
#ifdef __WXWINCE__
                case VER_PLATFORM_WIN32_CE:
                    s_ver = wxWINDOWS_CE;
#endif
            }
#endif
        }
    }

    static wxToolkitInfo info;
    info.versionMajor = s_major;
    info.versionMinor = s_minor;
    info.os = s_ver;
    info.name = _T("wxBase");
    return info;
}
Example #13
0
UINT GetMenuState(HMENU hMenu, UINT id, UINT flags)
{
    MENUITEMINFO info;
    wxZeroMemory(info);
    info.cbSize = sizeof(info);
    info.fMask = MIIM_STATE;
    // MF_BYCOMMAND is zero so test MF_BYPOSITION
    if ( !::GetMenuItemInfo(hMenu, id, flags & MF_BYPOSITION ? TRUE : FALSE , & info) )
        wxLogLastError(wxT("GetMenuItemInfo"));
    return info.fState;
}
Example #14
0
int wxCheckListBox::DoAppend(const wxString& item)
{
    int n = (int)GetCount();
    LVITEM newItem;
    wxZeroMemory(newItem);
    newItem.iItem = n;
    int ret = ListView_InsertItem( (HWND)GetHWND(), & newItem );
    wxCHECK_MSG( n == ret , -1, _T("Item not added") );
    SetString( ret , item );
    m_itemsClientData.Insert(NULL, ret);
    return ret;
}
Example #15
0
int wxScrollBar::GetThumbPosition(void) const
{
    SCROLLINFO scrollInfo;
    wxZeroMemory(scrollInfo);
    scrollInfo.cbSize = sizeof(SCROLLINFO);
    scrollInfo.fMask = SIF_POS;

    if ( !::GetScrollInfo(GetHwnd(), SB_CTL, &scrollInfo) )
    {
        wxLogLastError(wxT("GetScrollInfo"));
    }
    return scrollInfo.nPos;
}
Example #16
0
bool wxDIB::Create(int width, int height, int depth)
{
    // we don't support formats using palettes right now so we only create
    // either 24bpp (RGB) or 32bpp (RGBA) bitmaps
    wxASSERT_MSG( depth, wxT("invalid image depth in wxDIB::Create()") );
    if ( depth < 24 )
        depth = 24;

    // allocate memory for bitmap structures
    BITMAPINFO info;
    wxZeroMemory(info);

    info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    info.bmiHeader.biWidth = width;

    // we use positive height here which corresponds to a DIB with normal, i.e.
    // bottom to top, order -- normally using negative height (which means
    // reversed for MS and hence natural for all the normal people top to
    // bottom line scan order) could be used to avoid the need for the image
    // reversal in Create(image) but this doesn't work under NT, only Win9x!
    info.bmiHeader.biHeight = height;

    info.bmiHeader.biPlanes = 1;
    info.bmiHeader.biBitCount = (WORD)depth;
    info.bmiHeader.biSizeImage = GetLineSize(width, depth)*height;

    m_handle = ::CreateDIBSection
                 (
                    0,              // hdc (unused with DIB_RGB_COLORS)
                    &info,          // bitmap description
                    DIB_RGB_COLORS, // use RGB, not palette
                    &m_data,        // [out] DIB bits
                    NULL,           // don't use file mapping
                    0               // file mapping offset (not used here)
                 );

    if ( !m_handle )
    {
        wxLogLastError(wxT("CreateDIBSection"));

        return false;
    }

    m_width = width;
    m_height = height;
    m_depth = depth;

    return true;
}
Example #17
0
// make the given menu item default
static void SetDefaultMenuItem(HMENU WXUNUSED_IN_WINCE(hmenu),
                               UINT WXUNUSED_IN_WINCE(id))
{
#ifndef __WXWINCE__
    MENUITEMINFO mii;
    wxZeroMemory(mii);
    mii.cbSize = sizeof(MENUITEMINFO);
    mii.fMask = MIIM_STATE;
    mii.fState = MFS_DEFAULT;

    if ( !::SetMenuItemInfo(hmenu, id, FALSE, &mii) )
    {
        wxLogLastError(wxT("SetMenuItemInfo"));
    }
#endif
}
Example #18
0
void wxCheckListBox::DoInsertItems(const wxArrayString& items, unsigned int pos)
{
    wxCHECK_RET( IsValidInsert( pos ),
                 wxT("invalid index in wxListBox::InsertItems") );

    for( unsigned int i = 0; i < items.GetCount(); i++ )
    {
        LVITEM newItem;
        wxZeroMemory(newItem);
        newItem.iItem = i+pos;
        int ret = ListView_InsertItem( (HWND)GetHWND(), & newItem );
        wxASSERT_MSG( int(i+pos) == ret , _T("Item not added") );
        SetString( ret , items[i] );
        m_itemsClientData.Insert(NULL, ret);
    }
}
Example #19
0
/*
  Creates a hidden window with supplied window proc registering the class for
  it if necesssary (i.e. the first time only). Caller is responsible for
  destroying the window and unregistering the class (note that this must be
  done because wxWidgets may be used as a DLL and so may be loaded/unloaded
  multiple times into/from the same process so we cna't rely on automatic
  Windows class unregistration).

  pclassname is a pointer to a caller stored classname, which must initially be
  NULL. classname is the desired wndclass classname. If function successfully
  registers the class, pclassname will be set to classname.
 */
extern "C" WXDLLIMPEXP_BASE HWND
wxCreateHiddenWindow(LPCTSTR *pclassname, LPCTSTR classname, WNDPROC wndproc)
{
    wxCHECK_MSG( classname && pclassname && wndproc, NULL,
                    _T("NULL parameter in wxCreateHiddenWindow") );

    // register the class fi we need to first
    if ( *pclassname == NULL )
    {
        WNDCLASS wndclass;
        wxZeroMemory(wndclass);

        wndclass.lpfnWndProc   = wndproc;
        wndclass.hInstance     = wxGetInstance();
        wndclass.lpszClassName = classname;

        if ( !::RegisterClass(&wndclass) )
        {
            wxLogLastError(wxT("RegisterClass() in wxCreateHiddenWindow"));

            return NULL;
        }

        *pclassname = classname;
    }

    // next create the window
    HWND hwnd = ::CreateWindow
                  (
                    *pclassname,
                    NULL,
                    0, 0, 0, 0,
                    0,
                    (HWND) NULL,
                    (HMENU)NULL,
                    wxGetInstance(),
                    (LPVOID) NULL
                  );

    if ( !hwnd )
    {
        wxLogLastError(wxT("CreateWindow() in wxCreateHiddenWindow"));
    }

    return hwnd;
}
Example #20
0
bool wxCheckOsVersion(int majorVsn, int minorVsn)
{
    OSVERSIONINFOEX osvi;
    wxZeroMemory(osvi);
    osvi.dwOSVersionInfoSize = sizeof(osvi);

    DWORDLONG const dwlConditionMask =
        ::VerSetConditionMask(
            ::VerSetConditionMask(
                0, VER_MAJORVERSION, VER_GREATER_EQUAL),
            VER_MINORVERSION, VER_GREATER_EQUAL);

    osvi.dwMajorVersion = majorVsn;
    osvi.dwMinorVersion = minorVsn;

    return ::VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask) != FALSE;
}
Example #21
0
bool wxDIB::Save(const wxString& filename)
{
    wxCHECK_MSG( m_handle, false, wxT("wxDIB::Save(): invalid object") );

#if wxUSE_FILE
    wxFile file(filename, wxFile::write);
    bool ok = file.IsOpened();
    if ( ok )
    {
        DIBSECTION ds;
        if ( !GetDIBSection(m_handle, &ds) )
        {
            wxLogLastError(wxT("GetObject(hDIB)"));
        }
        else
        {
            BITMAPFILEHEADER bmpHdr;
            wxZeroMemory(bmpHdr);

            const size_t sizeHdr = ds.dsBmih.biSize;
            const size_t sizeImage = ds.dsBmih.biSizeImage;

            bmpHdr.bfType = 0x4d42;    // 'BM' in little endian
            bmpHdr.bfOffBits = sizeof(BITMAPFILEHEADER) + ds.dsBmih.biSize;
            bmpHdr.bfSize = bmpHdr.bfOffBits + sizeImage;

            // first write the file header, then the bitmap header and finally the
            // bitmap data itself
            ok = file.Write(&bmpHdr, sizeof(bmpHdr)) == sizeof(bmpHdr) &&
                    file.Write(&ds.dsBmih, sizeHdr) == sizeHdr &&
                        file.Write(ds.dsBm.bmBits, sizeImage) == sizeImage;
        }
    }
#else // !wxUSE_FILE
    bool ok = false;
#endif // wxUSE_FILE/!wxUSE_FILE

    if ( !ok )
    {
        wxLogError(_("Failed to save the bitmap image to file \"%s\"."),
                   filename.c_str());
    }

    return ok;
}
Example #22
0
// By John Skiff
int wxKillAllChildren(long pid, wxSignal sig, wxKillError *krc)
{
    InitToolHelp32();

    if (krc)
        *krc = wxKILL_OK;

    // If not implemented for this platform (e.g. NT 4.0), silently ignore
    if (!lpfCreateToolhelp32Snapshot || !lpfProcess32First || !lpfProcess32Next)
        return 0;

    // Take a snapshot of all processes in the system.
    HANDLE hProcessSnap = lpfCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hProcessSnap == INVALID_HANDLE_VALUE) {
        if (krc)
            *krc = wxKILL_ERROR;
        return -1;
    }

    //Fill in the size of the structure before using it.
    PROCESSENTRY32 pe;
    wxZeroMemory(pe);
    pe.dwSize = sizeof(PROCESSENTRY32);

    // Walk the snapshot of the processes, and for each process,
    // kill it if its parent is pid.
    if (!lpfProcess32First(hProcessSnap, &pe)) {
        // Can't get first process.
        if (krc)
            *krc = wxKILL_ERROR;
        CloseHandle (hProcessSnap);
        return -1;
    }

    do {
        if (pe.th32ParentProcessID == (DWORD) pid) {
            if (wxKill(pe.th32ProcessID, sig, krc))
                return -1;
        }
    } while (lpfProcess32Next (hProcessSnap, &pe));


    return 0;
}
Example #23
0
bool wxTestFontEncoding(const wxNativeEncodingInfo& info)
{
    // try to create such font
    LOGFONT lf;
    wxZeroMemory(lf);       // all default values

    lf.lfCharSet = (BYTE)info.charset;
    wxStrlcpy(lf.lfFaceName, info.facename.c_str(), WXSIZEOF(lf.lfFaceName));

    HFONT hfont = ::CreateFontIndirect(&lf);
    if ( !hfont )
    {
        // no such font
        return false;
    }

    ::DeleteObject((HGDIOBJ)hfont);

    return true;
}
Example #24
0
bool wxCheckListBox::Create(wxWindow *parent, wxWindowID id,
                            const wxPoint& pos, const wxSize& size,
                            int n, const wxString choices[],
                            long style,
                            const wxValidator& validator, const wxString& name)
{
    // initialize base class fields
    if ( !CreateControl(parent, id, pos, size, style, validator, name) )
        return false;

    // create the native control
    if ( !MSWCreateControl(WC_LISTVIEW, wxEmptyString, pos, size) )
    {
        // control creation failed
        return false;
    }

    ::SendMessage(GetHwnd(), LVM_SETEXTENDEDLISTVIEWSTYLE, 0,
                  LVS_EX_CHECKBOXES | LVS_EX_FULLROWSELECT );

    // insert single column with checkboxes and labels
    LV_COLUMN col;
    wxZeroMemory(col);
    ListView_InsertColumn(GetHwnd(), 0, &col );

    ListView_SetItemCount( GetHwnd(), n );

    // initialize the contents
    for ( int i = 0; i < n; i++ )
    {
        Append(choices[i]);
    }

    m_itemsClientData.SetCount(n);

    // now we can compute our best size correctly, so do it if necessary
    SetInitialSize(size);

    return true;
}
Example #25
0
wxCrashContext::wxCrashContext(_EXCEPTION_POINTERS *ep)
{
    wxZeroMemory(*this);

    if ( !ep )
    {
        wxCHECK_RET( wxGlobalSEInformation, wxT("no exception info available") );
        ep = wxGlobalSEInformation;
    }

    // TODO: we could also get the operation (read/write) and address for which
    //       it failed for EXCEPTION_ACCESS_VIOLATION code
    const EXCEPTION_RECORD& rec = *ep->ExceptionRecord;
    code = rec.ExceptionCode;
    addr = rec.ExceptionAddress;

#ifdef __INTEL__
    const CONTEXT& ctx = *ep->ContextRecord;
    regs.eax = ctx.Eax;
    regs.ebx = ctx.Ebx;
    regs.ecx = ctx.Ecx;
    regs.edx = ctx.Edx;
    regs.esi = ctx.Esi;
    regs.edi = ctx.Edi;

    regs.ebp = ctx.Ebp;
    regs.esp = ctx.Esp;
    regs.eip = ctx.Eip;

    regs.cs = ctx.SegCs;
    regs.ds = ctx.SegDs;
    regs.es = ctx.SegEs;
    regs.fs = ctx.SegFs;
    regs.gs = ctx.SegGs;
    regs.ss = ctx.SegSs;

    regs.flags = ctx.EFlags;
#endif // __INTEL__
}
Example #26
0
wxPortId wxGUIAppTraits::GetToolkitVersion(int *majVer, int *minVer) const
{
    OSVERSIONINFO info;
    wxZeroMemory(info);

    // on Windows, the toolkit version is the same of the OS version
    // as Windows integrates the OS kernel with the GUI toolkit.
    info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    if ( ::GetVersionEx(&info) )
    {
        if ( majVer )
            *majVer = info.dwMajorVersion;
        if ( minVer )
            *minVer = info.dwMinorVersion;
    }

#if defined(__WXHANDHELD__) || defined(__WXWINCE__)
    return wxPORT_WINCE;
#else
    return wxPORT_MSW;
#endif
}
Example #27
0
bool wxScrollBar::MSWOnScroll(int WXUNUSED(orientation), WXWORD wParam,
                              WXWORD pos, WXHWND WXUNUSED(control))
{
    // current and max positions
    int position,
        maxPos, trackPos = pos;

    wxUnusedVar(trackPos);

    // when we're dragging the scrollbar we can't use pos parameter because it
    // is limited to 16 bits
    // JACS: now always using GetScrollInfo, since there's no reason
    // not to
//    if ( wParam == SB_THUMBPOSITION || wParam == SB_THUMBTRACK )
    {
        SCROLLINFO scrollInfo;
        wxZeroMemory(scrollInfo);
        scrollInfo.cbSize = sizeof(SCROLLINFO);

        // also get the range if we call GetScrollInfo() anyhow -- this is less
        // expensive than call it once here and then call GetScrollRange()
        // below
        scrollInfo.fMask = SIF_RANGE | SIF_POS | SIF_TRACKPOS;

        if ( !::GetScrollInfo(GetHwnd(), SB_CTL, &scrollInfo) )
        {
            wxLogLastError(_T("GetScrollInfo"));
        }

        trackPos = scrollInfo.nTrackPos;
        position = scrollInfo.nPos;
        maxPos = scrollInfo.nMax;
    }
#if 0
    else
    {
Example #28
0
/* static */ wxString
wxDbgHelpDLL::DumpUDT(PSYMBOL_INFO pSym, void *pVariable, unsigned level)
{
    wxString s;

    // we have to limit the depth of UDT dumping as otherwise we get in
    // infinite loops trying to dump linked lists... 10 levels seems quite
    // reasonable, full information is in minidump file anyhow
    if ( level > 10 )
        return s;

    s.reserve(512);
    s = GetSymbolName(pSym);

#if !wxUSE_STL
    // special handling for ubiquitous wxString: although the code below works
    // for it as well, it shows the wxStringBase class and takes 4 lines
    // instead of only one as this branch
    if ( s == _T("wxString") )
    {
        wxString *ps = (wxString *)pVariable;
        s << _T("(\"") << *ps << _T(")\"");
    }
    else // any other UDT
#endif // !wxUSE_STL
    {
        // Determine how many children this type has.
        DWORD dwChildrenCount = 0;
        DoGetTypeInfo(pSym, TI_GET_CHILDRENCOUNT, &dwChildrenCount);

        // Prepare to get an array of "TypeIds", representing each of the children.
        TI_FINDCHILDREN_PARAMS *children = (TI_FINDCHILDREN_PARAMS *)
            malloc(sizeof(TI_FINDCHILDREN_PARAMS) +
                        (dwChildrenCount - 1)*sizeof(ULONG));
        if ( !children )
            return s;

        children->Count = dwChildrenCount;
        children->Start = 0;

        // Get the array of TypeIds, one for each child type
        if ( !DoGetTypeInfo(pSym, TI_FINDCHILDREN, children) )
        {
            free(children);
            return s;
        }

        s << _T(" {\n");

        // Iterate through all children
        SYMBOL_INFO sym;
        wxZeroMemory(sym);
        sym.ModBase = pSym->ModBase;
        for ( unsigned i = 0; i < dwChildrenCount; i++ )
        {
            sym.TypeIndex = children->ChildId[i];

            // children here are in lexicographic sense, i.e. we get all our nested
            // classes and not only our member fields, but we can't get the values
            // for the members of the nested classes, of course!
            DWORD nested;
            if ( DoGetTypeInfo(&sym, TI_GET_NESTED, &nested) && nested )
                continue;

            // avoid infinite recursion: this does seem to happen sometimes with
            // complex typedefs...
            if ( sym.TypeIndex == pSym->TypeIndex )
                continue;

            s += DumpField(&sym, pVariable, level + 1);
        }

        free(children);

        s << wxString(_T('\t'), level + 1) << _T('}');
    }

    return s;
}
Example #29
0
bool wxDisplayImplMultimon::ChangeMode(const wxVideoMode& mode)
{
    // prepare ChangeDisplaySettingsEx() parameters
    DEVMODE dm;
    DEVMODE *pDevMode;

    int flags;

    if ( mode == wxDefaultVideoMode )
    {
        // reset the video mode to default
        pDevMode = NULL;
        flags = 0;
    }
    else // change to the given mode
    {
        wxCHECK_MSG( mode.GetWidth() && mode.GetHeight(), false,
                        wxT("at least the width and height must be specified") );

        wxZeroMemory(dm);
        dm.dmSize = sizeof(dm);
        dm.dmDriverExtra = 0;
        dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
        dm.dmPelsWidth = mode.GetWidth();
        dm.dmPelsHeight = mode.GetHeight();

        if ( mode.GetDepth() )
        {
            dm.dmFields |= DM_BITSPERPEL;
            dm.dmBitsPerPel = mode.GetDepth();
        }

        if ( mode.GetRefresh() )
        {
            dm.dmFields |= DM_DISPLAYFREQUENCY;
            dm.dmDisplayFrequency = mode.GetRefresh();
        }

        pDevMode = &dm;

#ifdef __WXWINCE__
        flags = 0;
#else // !__WXWINCE__
        flags = CDS_FULLSCREEN;
#endif // __WXWINCE__/!__WXWINCE__
    }


    // get pointer to the function dynamically
    //
    // we're only called from the main thread, so it's ok to use static
    // variable
    static ChangeDisplaySettingsEx_t pfnChangeDisplaySettingsEx = NULL;
    if ( !pfnChangeDisplaySettingsEx )
    {
        wxDynamicLibrary dllDisplay(displayDllName, wxDL_VERBATIM | wxDL_QUIET);
        if ( dllDisplay.IsLoaded() )
        {
            wxDL_INIT_FUNC_AW(pfn, ChangeDisplaySettingsEx, dllDisplay);
        }
        //else: huh, no this DLL must always be present, what's going on??

#ifndef __WXWINCE__
        if ( !pfnChangeDisplaySettingsEx )
        {
            // we must be under Win95 and so there is no multiple monitors
            // support anyhow
            pfnChangeDisplaySettingsEx = ChangeDisplaySettingsExForWin95;
        }
#endif // !__WXWINCE__
    }

    // do change the mode
    switch ( pfnChangeDisplaySettingsEx
             (
                GetName().wx_str(), // display name
                pDevMode,           // dev mode or NULL to reset
                NULL,               // reserved
                flags,
                NULL                // pointer to video parameters (not used)
             ) )
    {
        case DISP_CHANGE_SUCCESSFUL:
            // ok
            {
                // If we have a top-level, full-screen frame, emulate
                // the DirectX behavior and resize it.  This makes this
                // API quite a bit easier to use.
                wxWindow *winTop = wxTheApp->GetTopWindow();
                wxFrame *frameTop = wxDynamicCast(winTop, wxFrame);
                if (frameTop && frameTop->IsFullScreen())
                {
                    wxVideoMode current = GetCurrentMode();
                    frameTop->SetClientSize(current.GetWidth(), current.GetHeight());
                }
            }
            return true;

        case DISP_CHANGE_BADMODE:
            // don't complain about this, this is the only "expected" error
            break;

        default:
            wxFAIL_MSG( wxT("unexpected ChangeDisplaySettingsEx() return value") );
    }

    return false;
}
Example #30
0
long wxExecute(const wxString& cmd, int flags, wxProcess *handler,
               const wxExecuteEnv *env)
{
    wxCHECK_MSG( !cmd.empty(), 0, wxT("empty command in wxExecute") );

#if wxUSE_THREADS
    // for many reasons, the code below breaks down if it's called from another
    // thread -- this could be fixed, but as Unix versions don't support this
    // neither I don't want to waste time on this now
    wxASSERT_MSG( wxThread::IsMain(),
                    wxT("wxExecute() can be called only from the main thread") );
#endif // wxUSE_THREADS

    wxString command;

#if wxUSE_IPC
    // DDE hack: this is really not pretty, but we need to allow this for
    // transparent handling of DDE servers in wxMimeTypesManager. Usually it
    // returns the command which should be run to view/open/... a file of the
    // given type. Sometimes, however, this command just launches the server
    // and an additional DDE request must be made to really open the file. To
    // keep all this well hidden from the application, we allow a special form
    // of command: WX_DDE#<command>#DDE_SERVER#DDE_TOPIC#DDE_COMMAND in which
    // case we execute just <command> and process the rest below
    wxString ddeServer, ddeTopic, ddeCommand;
    static const size_t lenDdePrefix = 7;   // strlen("WX_DDE:")
    if ( cmd.Left(lenDdePrefix) == wxT("WX_DDE#") )
    {
        // speed up the concatenations below
        ddeServer.reserve(256);
        ddeTopic.reserve(256);
        ddeCommand.reserve(256);

        const wxChar *p = cmd.c_str() + 7;
#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
        while ( *p && *p != wxT('#') )
        {
            command += *p++;
        }

        if ( *p )
        {
            // skip '#'
            p++;
        }
        else
        {
            wxFAIL_MSG(wxT("invalid WX_DDE command in wxExecute"));
        }

#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
        while ( *p && *p != wxT('#') )
        {
            ddeServer += *p++;
        }

        if ( *p )
        {
            // skip '#'
            p++;
        }
        else
        {
            wxFAIL_MSG(wxT("invalid WX_DDE command in wxExecute"));
        }

#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
        while ( *p && *p != wxT('#') )
        {
            ddeTopic += *p++;
        }

        if ( *p )
        {
            // skip '#'
            p++;
        }
        else
        {
            wxFAIL_MSG(wxT("invalid WX_DDE command in wxExecute"));
        }

#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
        while ( *p )
        {
            ddeCommand += *p++;
        }

        // if we want to just launch the program and not wait for its
        // termination, try to execute DDE command right now, it can succeed if
        // the process is already running - but as it fails if it's not
        // running, suppress any errors it might generate
        if ( !(flags & wxEXEC_SYNC) )
        {
            wxLogNull noErrors;
            if ( wxExecuteDDE(ddeServer, ddeTopic, ddeCommand) )
            {
                // a dummy PID - this is a hack, of course, but it's well worth
                // it as we don't open a new server each time we're called
                // which would be quite bad
                return -1;
            }
        }
    }
    else
#endif // wxUSE_IPC
    {
        // no DDE
        command = cmd;
    }

    // the IO redirection is only supported with wxUSE_STREAMS
    BOOL redirect = FALSE;

#if wxUSE_STREAMS
    wxPipe pipeIn, pipeOut, pipeErr;

    // open the pipes to which child process IO will be redirected if needed
    if ( handler && handler->IsRedirected() )
    {
        // create pipes for redirecting stdin, stdout and stderr
        if ( !pipeIn.Create() || !pipeOut.Create() || !pipeErr.Create() )
        {
            wxLogSysError(_("Failed to redirect the child process IO"));

            // indicate failure: we need to return different error code
            // depending on the sync flag
            return flags & wxEXEC_SYNC ? -1 : 0;
        }

        redirect = TRUE;
    }
#endif // wxUSE_STREAMS

    // create the process
    STARTUPINFO si;
    wxZeroMemory(si);
    si.cb = sizeof(si);

#if wxUSE_STREAMS
    if ( redirect )
    {
        si.dwFlags = STARTF_USESTDHANDLES;

        si.hStdInput = pipeIn[wxPipe::Read];
        si.hStdOutput = pipeOut[wxPipe::Write];
        si.hStdError = pipeErr[wxPipe::Write];

        // We must set the handles to those sides of std* pipes that we won't
        // in the child to be non-inheritable. We must do this before launching
        // the child process as otherwise these handles will be inherited by
        // the child which will never close them and so the pipe will not
        // return ERROR_BROKEN_PIPE if the parent or child exits unexpectedly
        // causing the remaining process to potentially become deadlocked in
        // ReadFile() or WriteFile().
        if ( !::SetHandleInformation(pipeIn[wxPipe::Write],
                                     HANDLE_FLAG_INHERIT, 0) )
            wxLogLastError(wxT("SetHandleInformation(pipeIn)"));

        if ( !::SetHandleInformation(pipeOut[wxPipe::Read],
                                     HANDLE_FLAG_INHERIT, 0) )
            wxLogLastError(wxT("SetHandleInformation(pipeOut)"));

        if ( !::SetHandleInformation(pipeErr[wxPipe::Read],
                                     HANDLE_FLAG_INHERIT, 0) )
            wxLogLastError(wxT("SetHandleInformation(pipeErr)"));
    }
#endif // wxUSE_STREAMS

    // The default logic for showing the console is to show it only if the IO
    // is not redirected however wxEXEC_{SHOW,HIDE}_CONSOLE flags can be
    // explicitly specified to change it.
    if ( (flags & wxEXEC_HIDE_CONSOLE) ||
            (redirect && !(flags & wxEXEC_SHOW_CONSOLE)) )
    {
        si.dwFlags |= STARTF_USESHOWWINDOW;
        si.wShowWindow = SW_HIDE;
    }


    PROCESS_INFORMATION pi;
    DWORD dwFlags = CREATE_SUSPENDED;

    if ( (flags & wxEXEC_MAKE_GROUP_LEADER) )
        dwFlags |= CREATE_NEW_PROCESS_GROUP;

    dwFlags |= CREATE_DEFAULT_ERROR_MODE ;

    wxWxCharBuffer envBuffer;
    bool useCwd = false;
    if ( env )
    {
        useCwd = !env->cwd.empty();

        // Translate environment variable map into NUL-terminated list of
        // NUL-terminated strings.
        if ( !env->env.empty() )
        {
#if wxUSE_UNICODE
            // Environment variables can contain non-ASCII characters. We could
            // check for it and not use this flag if everything is really ASCII
            // only but there doesn't seem to be any reason to do it so just
            // assume Unicode by default.
            dwFlags |= CREATE_UNICODE_ENVIRONMENT;
#endif // wxUSE_UNICODE

            wxEnvVariableHashMap::const_iterator it;

            size_t envSz = 1; // ending '\0'
#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
            for ( it = env->env.begin(); it != env->env.end(); ++it )
            {
                // Add size of env variable name and value, and '=' char and
                // ending '\0'
                envSz += it->first.length() + it->second.length() + 2;
            }

            envBuffer.extend(envSz);

            wxChar *p = envBuffer.data();
#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
            for ( it = env->env.begin(); it != env->env.end(); ++it )
            {
                const wxString line = it->first + wxS("=") + it->second;

                // Include the trailing NUL which will always terminate the
                // buffer returned by t_str().
                const size_t len = line.length() + 1;

                wxTmemcpy(p, line.t_str(), len);

                p += len;
            }

            // And another NUL to terminate the list of NUL-terminated strings.
            *p = 0;
        }
    }

    // Translate wxWidgets priority to Windows conventions.
    if ( handler )
    {
        unsigned prio = handler->GetPriority();
        if ( prio <= 20 )
            dwFlags |= IDLE_PRIORITY_CLASS;
        else if ( prio <= 40 )
            dwFlags |= BELOW_NORMAL_PRIORITY_CLASS;
        else if ( prio <= 60 )
            dwFlags |= NORMAL_PRIORITY_CLASS;
        else if ( prio <= 80 )
            dwFlags |= ABOVE_NORMAL_PRIORITY_CLASS;
        else if ( prio <= 99 )
            dwFlags |= HIGH_PRIORITY_CLASS;
        else if ( prio <= 100 )
            dwFlags |= REALTIME_PRIORITY_CLASS;
        else
        {
            wxFAIL_MSG(wxT("invalid value of thread priority parameter"));
            dwFlags |= NORMAL_PRIORITY_CLASS;
        }
    }

    bool ok = ::CreateProcess
                (
                 NULL,               // application name (use only cmd line)
                 wxMSW_CONV_LPTSTR(command), // full command line
                 NULL,               // security attributes: defaults for both
                 NULL,               //   the process and its main thread
                 redirect,           // inherit handles if we use pipes
                 dwFlags,            // process creation flags
                 envBuffer.data(),   // environment (may be NULL which is fine)
                 useCwd              // initial working directory
                    ? wxMSW_CONV_LPTSTR(env->cwd)
                    : NULL,          //     (or use the same)
                 &si,                // startup info (unused here)
                 &pi                 // process info
                ) != 0;

#if wxUSE_STREAMS
    // we can close the pipe ends used by child anyhow
    if ( redirect )
    {
        ::CloseHandle(pipeIn.Detach(wxPipe::Read));
        ::CloseHandle(pipeOut.Detach(wxPipe::Write));
        ::CloseHandle(pipeErr.Detach(wxPipe::Write));
    }
#endif // wxUSE_STREAMS

    if ( !ok )
    {
#if wxUSE_STREAMS
        // close the other handles too
        if ( redirect )
        {
            ::CloseHandle(pipeIn.Detach(wxPipe::Write));
            ::CloseHandle(pipeOut.Detach(wxPipe::Read));
            ::CloseHandle(pipeErr.Detach(wxPipe::Read));
        }
#endif // wxUSE_STREAMS

        wxLogSysError(_("Execution of command '%s' failed"), command.c_str());

        return flags & wxEXEC_SYNC ? -1 : 0;
    }

#if wxUSE_STREAMS
    // the input buffer bufOut is connected to stdout, this is why it is
    // called bufOut and not bufIn
    wxStreamTempInputBuffer bufOut,
                            bufErr;

    if ( redirect )
    {
        // We can now initialize the wxStreams
        wxPipeInputStream *
            outStream = new wxPipeInputStream(pipeOut.Detach(wxPipe::Read));
        wxPipeInputStream *
            errStream = new wxPipeInputStream(pipeErr.Detach(wxPipe::Read));
        wxPipeOutputStream *
            inStream = new wxPipeOutputStream(pipeIn.Detach(wxPipe::Write));

        handler->SetPipeStreams(outStream, inStream, errStream);

        bufOut.Init(outStream);
        bufErr.Init(errStream);
    }
#endif // wxUSE_STREAMS

    // create a hidden window to receive notification about process
    // termination
    HWND hwnd = wxCreateHiddenWindow
                (
                    &gs_classForHiddenWindow,
                    wxMSWEXEC_WNDCLASSNAME,
                    (WNDPROC)wxExecuteWindowCbk
                );

    wxASSERT_MSG( hwnd, wxT("can't create a hidden window for wxExecute") );

    // Alloc data
    wxExecuteData *data = new wxExecuteData;
    data->hProcess    = pi.hProcess;
    data->dwProcessId = pi.dwProcessId;
    data->hWnd        = hwnd;
    data->state       = (flags & wxEXEC_SYNC) != 0;
    if ( flags & wxEXEC_SYNC )
    {
        // handler may be !NULL for capturing program output, but we don't use
        // it wxExecuteData struct in this case
        data->handler = NULL;
    }
    else
    {
        // may be NULL or not
        data->handler = handler;

        if (handler)
            handler->SetPid(pi.dwProcessId);
    }

    DWORD tid;
    HANDLE hThread = ::CreateThread(NULL,
                                    0,
                                    wxExecuteThread,
                                    (void *)data,
                                    0,
                                    &tid);

    // resume process we created now - whether the thread creation succeeded or
    // not
    if ( ::ResumeThread(pi.hThread) == (DWORD)-1 )
    {
        // ignore it - what can we do?
        wxLogLastError(wxT("ResumeThread in wxExecute"));
    }

    // close unneeded handle
    if ( !::CloseHandle(pi.hThread) )
    {
        wxLogLastError(wxT("CloseHandle(hThread)"));
    }

    if ( !hThread )
    {
        wxLogLastError(wxT("CreateThread in wxExecute"));

        DestroyWindow(hwnd);
        delete data;

        // the process still started up successfully...
        return pi.dwProcessId;
    }

    gs_asyncThreads.push_back(hThread);
    data->hThread = hThread;

#if wxUSE_IPC
    // second part of DDE hack: now establish the DDE conversation with the
    // just launched process
    if ( !ddeServer.empty() )
    {
        bool ddeOK;

        // give the process the time to init itself
        //
        // we use a very big timeout hoping that WaitForInputIdle() will return
        // much sooner, but not INFINITE just in case the process hangs
        // completely - like this we will regain control sooner or later
        switch ( ::WaitForInputIdle(pi.hProcess, 10000 /* 10 seconds */) )
        {
            default:
                wxFAIL_MSG( wxT("unexpected WaitForInputIdle() return code") );
                // fall through

            case WAIT_FAILED:
                wxLogLastError(wxT("WaitForInputIdle() in wxExecute"));

            case WAIT_TIMEOUT:
                wxLogDebug(wxT("Timeout too small in WaitForInputIdle"));

                ddeOK = false;
                break;

            case 0:
                // ok, process ready to accept DDE requests
                ddeOK = wxExecuteDDE(ddeServer, ddeTopic, ddeCommand);
        }

        if ( !ddeOK )
        {
            wxLogDebug(wxT("Failed to send DDE request to the process \"%s\"."),
                       cmd.c_str());
        }
    }
#endif // wxUSE_IPC

    if ( !(flags & wxEXEC_SYNC) )
    {
        // clean up will be done when the process terminates

        // return the pid
        return pi.dwProcessId;
    }

    wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
    wxCHECK_MSG( traits, -1, wxT("no wxAppTraits in wxExecute()?") );

    void *cookie = NULL;
    if ( !(flags & wxEXEC_NODISABLE) )
    {
        // disable all app windows while waiting for the child process to finish
        cookie = traits->BeforeChildWaitLoop();
    }

    // wait until the child process terminates
#if defined(__INTEL_COMPILER) && 1 /* VDM auto patch */
#   pragma ivdep
#   pragma swp
#   pragma unroll
#   pragma prefetch
#   if 0
#       pragma simd noassert
#   endif
#endif /* VDM auto patch */
    while ( data->state )
    {
#if wxUSE_STREAMS
        if ( !bufOut.Update() && !bufErr.Update() )
#endif // wxUSE_STREAMS
        {
            // don't eat 100% of the CPU -- ugly but anything else requires
            // real async IO which we don't have for the moment
            ::Sleep(50);
        }

        // we must always process messages for our hidden window or we'd never
        // get wxWM_PROC_TERMINATED and so this loop would never terminate
        MSG msg;
        ::PeekMessage(&msg, data->hWnd, 0, 0, PM_REMOVE);

        // we may also need to process messages for all the other application
        // windows
        if ( !(flags & wxEXEC_NOEVENTS) )
        {
            wxEventLoopBase * const loop = wxEventLoopBase::GetActive();
            if ( loop )
                loop->Yield();
        }
    }

    if ( !(flags & wxEXEC_NODISABLE) )
    {
        // reenable disabled windows back
        traits->AfterChildWaitLoop(cookie);
    }

    DWORD dwExitCode = data->dwExitCode;
    delete data;

    // return the exit code
    return dwExitCode;
}