1. wxThread changes (detached/joinable) for MSW and docs updates
2. wxUSE_GUI=0 compilation for MSW (use vc6dll.t with tmake) and many small fixes related to this 3. an attempt to make wxLog more MT friendly 4. a small fix for wxRegConfig: it doesn't create empty unused keys any more (SetPath() would always create a key, now it's deleted if it was empty) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4712 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -239,7 +239,7 @@ iniconf.cpp M 16
|
|||||||
joystick.cpp M
|
joystick.cpp M
|
||||||
listbox.cpp M
|
listbox.cpp M
|
||||||
listctrl.cpp M 32
|
listctrl.cpp M 32
|
||||||
main.cpp M
|
main.cpp M B
|
||||||
mdi.cpp M
|
mdi.cpp M
|
||||||
menu.cpp M
|
menu.cpp M
|
||||||
menuitem.cpp M
|
menuitem.cpp M
|
||||||
@@ -258,9 +258,9 @@ printdlg.cpp M
|
|||||||
printwin.cpp M
|
printwin.cpp M
|
||||||
radiobox.cpp M
|
radiobox.cpp M
|
||||||
radiobut.cpp M
|
radiobut.cpp M
|
||||||
regconf.cpp M 32
|
regconf.cpp M 32,B
|
||||||
region.cpp M
|
region.cpp M
|
||||||
registry.cpp M 32
|
registry.cpp M 32,B
|
||||||
scrolbar.cpp M
|
scrolbar.cpp M
|
||||||
settings.cpp M
|
settings.cpp M
|
||||||
slider95.cpp M 32
|
slider95.cpp M 32
|
||||||
@@ -277,12 +277,12 @@ taskbar.cpp M 32
|
|||||||
tbar95.cpp M 32
|
tbar95.cpp M 32
|
||||||
tbarmsw.cpp M 16
|
tbarmsw.cpp M 16
|
||||||
textctrl.cpp M
|
textctrl.cpp M
|
||||||
thread.cpp M 32
|
thread.cpp M 32,B
|
||||||
timer.cpp M
|
timer.cpp M
|
||||||
tooltip.cpp M 32
|
tooltip.cpp M 32
|
||||||
treectrl.cpp M 32
|
treectrl.cpp M 32
|
||||||
utils.cpp M
|
utils.cpp M B
|
||||||
utilsexc.cpp M
|
utilsexc.cpp M B
|
||||||
uuid.cpp M O
|
uuid.cpp M O
|
||||||
wave.cpp M
|
wave.cpp M
|
||||||
window.cpp M
|
window.cpp M
|
||||||
@@ -292,7 +292,7 @@ gsocket.c M S
|
|||||||
dialup.cpp U
|
dialup.cpp U
|
||||||
fontenum.cpp U
|
fontenum.cpp U
|
||||||
fontutil.cpp U
|
fontutil.cpp U
|
||||||
threadpsx.cpp U
|
threadpsx.cpp U B
|
||||||
utilsunx.cpp U B
|
utilsunx.cpp U B
|
||||||
gsocket.c U
|
gsocket.c U
|
||||||
|
|
||||||
|
@@ -81,7 +81,7 @@ RSC=rc.exe
|
|||||||
# PROP Intermediate_Dir "Release"
|
# PROP Intermediate_Dir "Release"
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
||||||
# ADD CPP /nologo /W3 /Zi /O2 /I "$(wx)\include" /I "$(wx)\src\zlib" /D "NDEBUG" /D WIN95=1 /D "__WIN95__" /D "WIN32" /D "_WIN32" /D WINVER=0x400 /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN32__" /Yu"wx/wxprec.h" /FD /c
|
# ADD CPP /nologo /W3 /Zi /O2 /I "$(wx)\include" /I "$(wx)\src\zlib" /D "NDEBUG" /D wxUSE_GUI=1 /D WIN95=1 /D "__WIN95__" /D "WIN32" /D "_WIN32" /D WINVER=0x400 /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN32__" /Yu"wx/wxprec.h" /FD /c
|
||||||
# ADD BASE RSC /l 0x409
|
# ADD BASE RSC /l 0x409
|
||||||
# ADD RSC /l 0x409
|
# ADD RSC /l 0x409
|
||||||
BSC32=bscmake.exe
|
BSC32=bscmake.exe
|
||||||
@@ -104,7 +104,7 @@ LIB32=link.exe -lib
|
|||||||
# PROP Intermediate_Dir "Debug"
|
# PROP Intermediate_Dir "Debug"
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
|
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
|
||||||
# ADD CPP /nologo /W4 /Zi /Od /I "$(wx)\include" /I "$(wx)\src\zlib" /D "_DEBUG" /D DEBUG=1 /D WXDEBUG=1 /D "__WXDEBUG__" /D "__WIN95__" /D "WIN32" /D "_WIN32" /D WINVER=0x400 /D "__WINDOWS__" /D "__WIN32__" /D "__WXMSW__" /Fr /Yu"wx/wxprec.h" /FD /c
|
# ADD CPP /nologo /W4 /Zi /Od /I "$(wx)\include" /I "$(wx)\src\zlib" /D "_DEBUG" /D DEBUG=1 /D WXDEBUG=1 /D "__WXDEBUG__" /D wxUSE_GUI=1 /D "__WIN95__" /D "WIN32" /D "_WIN32" /D WINVER=0x400 /D "__WINDOWS__" /D "__WIN32__" /D "__WXMSW__" /Fr /Yu"wx/wxprec.h" /FD /c
|
||||||
# ADD BASE RSC /l 0x409
|
# ADD BASE RSC /l 0x409
|
||||||
# ADD RSC /l 0x409
|
# ADD RSC /l 0x409
|
||||||
BSC32=bscmake.exe
|
BSC32=bscmake.exe
|
||||||
|
145
distrib/msw/tmake/vc6base.t
Normal file
145
distrib/msw/tmake/vc6base.t
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
#!#############################################################################
|
||||||
|
#! File: vc6base.t
|
||||||
|
#! Purpose: tmake template file from which wxBase.dsp is generated by running
|
||||||
|
#! tmake -t vc6base wxwin.pro -o wxBase.dsp
|
||||||
|
#! Author: Vadim Zeitlin
|
||||||
|
#! Created: 27.11.99
|
||||||
|
#! Version: $Id$
|
||||||
|
#!#############################################################################
|
||||||
|
#${
|
||||||
|
#! include the code which parses filelist.txt file and initializes
|
||||||
|
#! %wxCommon, %wxGeneric and %wxMSW hashes.
|
||||||
|
IncludeTemplate("filelist.t");
|
||||||
|
|
||||||
|
#! now transform these hashes into $project tags
|
||||||
|
foreach $file (sort keys %wxCommon) {
|
||||||
|
next if $wxCommon{$file} !~ /\bB\b/;
|
||||||
|
|
||||||
|
my $tag = $file =~ /\.c$/ ? "WXCSRCS" : "WXCOMMONSRCS";
|
||||||
|
$project{$tag} .= $file . " "
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach $file (sort keys %wxMSW) {
|
||||||
|
next if $wxMSW{$file} !~ /\bB\b/;
|
||||||
|
|
||||||
|
my $tag = $file =~ /\.c$/ ? "WXMSWCSRCS" : "WXMSWSRCS";
|
||||||
|
$project{$tag} .= $file . " "
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach $file (sort keys %wxBase) {
|
||||||
|
my $tag = $file =~ /\.c$/ ? "WXCSRCS" : "WXCOMMONSRCS";
|
||||||
|
$project{$tag} .= $file . " "
|
||||||
|
}
|
||||||
|
#$}
|
||||||
|
# Microsoft Developer Studio Project File - Name="wxBase" - Package Owner=<4>
|
||||||
|
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||||
|
# ** DO NOT EDIT **
|
||||||
|
|
||||||
|
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||||
|
|
||||||
|
CFG=wxBase - Win32 Debug
|
||||||
|
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||||
|
!MESSAGE use the Export Makefile command and run
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "wxBase.mak".
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE You can specify a configuration when running NMAKE
|
||||||
|
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE NMAKE /f "wxBase.mak" CFG="wxBase - Win32 Debug"
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE Possible choices for configuration are:
|
||||||
|
!MESSAGE
|
||||||
|
!MESSAGE "wxBase - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||||
|
!MESSAGE "wxBase - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||||
|
!MESSAGE
|
||||||
|
|
||||||
|
# Begin Project
|
||||||
|
# PROP AllowPerConfigDependencies 0
|
||||||
|
# PROP Scc_ProjName ""
|
||||||
|
# PROP Scc_LocalPath ""
|
||||||
|
CPP=cl.exe
|
||||||
|
RSC=rc.exe
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "wxBase - Win32 Release"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 0
|
||||||
|
# PROP BASE Output_Dir "Release"
|
||||||
|
# PROP BASE Intermediate_Dir "Release"
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 0
|
||||||
|
# PROP Output_Dir "Release"
|
||||||
|
# PROP Intermediate_Dir "Release"
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
|
||||||
|
# ADD CPP /nologo /W3 /Zi /O2 /I "$(wx)\include" /I "$(wx)\src\zlib" /D "NDEBUG" /D wxUSE_GUI=0 /D WIN95=1 /D "__WIN95__" /D "WIN32" /D "_WIN32" /D WINVER=0x400 /D "__WINDOWS__" /D "__WXMSW__" /D "__WIN32__" /Yu"wx/wxprec.h" /FD /c
|
||||||
|
# ADD BASE RSC /l 0x409
|
||||||
|
# ADD RSC /l 0x409
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo
|
||||||
|
LIB32=link.exe -lib
|
||||||
|
# ADD BASE LIB32 /nologo
|
||||||
|
# ADD LIB32 /nologo
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "wxBase - Win32 Debug"
|
||||||
|
|
||||||
|
# PROP BASE Use_MFC 0
|
||||||
|
# PROP BASE Use_Debug_Libraries 1
|
||||||
|
# PROP BASE Output_Dir "Debug"
|
||||||
|
# PROP BASE Intermediate_Dir "Debug"
|
||||||
|
# PROP BASE Target_Dir ""
|
||||||
|
# PROP Use_MFC 0
|
||||||
|
# PROP Use_Debug_Libraries 1
|
||||||
|
# PROP Output_Dir "Debug"
|
||||||
|
# PROP Intermediate_Dir "Debug"
|
||||||
|
# PROP Target_Dir ""
|
||||||
|
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
|
||||||
|
# ADD CPP /nologo /W4 /Zi /Od /I "$(wx)\include" /I "$(wx)\src\zlib" /D "_DEBUG" /D DEBUG=1 /D WXDEBUG=1 /D "__WXDEBUG__" /D wxUSE_GUI=0 /D "__WIN95__" /D "WIN32" /D "_WIN32" /D WINVER=0x400 /D "__WINDOWS__" /D "__WIN32__" /D "__WXMSW__" /Fr /Yu"wx/wxprec.h" /FD /c
|
||||||
|
# ADD BASE RSC /l 0x409
|
||||||
|
# ADD RSC /l 0x409
|
||||||
|
BSC32=bscmake.exe
|
||||||
|
# ADD BASE BSC32 /nologo
|
||||||
|
# ADD BSC32 /nologo /o"lib/wxBase.bsc"
|
||||||
|
LIB32=link.exe -lib
|
||||||
|
# ADD BASE LIB32 /nologo
|
||||||
|
# ADD LIB32 /nologo
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# Begin Target
|
||||||
|
|
||||||
|
# Name "wxBase - Win32 Release"
|
||||||
|
# Name "wxBase - Win32 Debug"
|
||||||
|
|
||||||
|
# PROP Default_Filter ""
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\src\msw\dummy.cpp
|
||||||
|
# ADD CPP /Yc"wx/wxprec.h"
|
||||||
|
# End Source File
|
||||||
|
#$ ExpandGlue("WXCOMMONSRCS", "# Begin Source File\n\nSOURCE=.\\src\\common\\", "\n# End Source File\n# Begin Source File\n\nSOURCE=.\\src\\common\\", "\n# End Source File\n");
|
||||||
|
#$ ExpandGlue("WXMSWSRCS", "# Begin Source File\n\nSOURCE=.\\src\\msw\\", "\n# End Source File\n# Begin Source File\n\nSOURCE=.\\src\\msw\\", "\n# End Source File\n");
|
||||||
|
#$ ExpandGlue("WXCSRCS", "# Begin Source File\n\nSOURCE=.\\src\\common\\", "\n# SUBTRACT CPP /YX /Yc /Yu\n# End Source File\n# Begin Source File\n\nSOURCE=.\\src\\common\\", "\n# SUBTRACT CPP /YX /Yc /Yu\n# End Source File\n");
|
||||||
|
#$ ExpandGlue("WXMSWCSRCS", "# Begin Source File\n\nSOURCE=.\\src\\msw\\", "\n# SUBTRACT CPP /YX /Yc /Yu\n# End Source File\n# Begin Source File\n\nSOURCE=.\\src\\common\\", "\n# SUBTRACT CPP /YX /Yc /Yu\n# End Source File\n");
|
||||||
|
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\src\common\y_tab.c
|
||||||
|
|
||||||
|
!IF "$(CFG)" == "wxBase - Win32 Release"
|
||||||
|
|
||||||
|
# SUBTRACT CPP /YX /Yc /Yu
|
||||||
|
|
||||||
|
!ELSEIF "$(CFG)" == "wxBase - Win32 Debug"
|
||||||
|
|
||||||
|
# ADD CPP /W1
|
||||||
|
# SUBTRACT CPP /YX /Yc /Yu
|
||||||
|
|
||||||
|
!ENDIF
|
||||||
|
|
||||||
|
# End Source File
|
||||||
|
# End Target
|
||||||
|
# End Project
|
@@ -83,7 +83,7 @@ RSC=rc.exe
|
|||||||
# PROP Ignore_Export_Lib 0
|
# PROP Ignore_Export_Lib 0
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /MT /W4 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "WXWINDLL_EXPORTS" /YX /FD /c
|
# ADD BASE CPP /nologo /MT /W4 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "WXWINDLL_EXPORTS" /YX /FD /c
|
||||||
# ADD CPP /nologo /MT /W4 /GX /O2 /I "$(wx)\include" /I "$(wx)\src\zlib" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "WXWINDLL_EXPORTS" /D "__WXMSW__" /D "__WIN95__" /D "__WINDOWS__" /D "__WIN32__" /D "WXMAKINGDLL" /Yu"wx/wxprec.h" /FD /c
|
# ADD CPP /nologo /MT /W4 /GX /O2 /I "$(wx)\include" /I "$(wx)\src\zlib" /D "NDEBUG" /D wxUSE_GUI=1 /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "WXWINDLL_EXPORTS" /D "__WXMSW__" /D "__WIN95__" /D "__WINDOWS__" /D "__WIN32__" /D "WXMAKINGDLL" /Yu"wx/wxprec.h" /FD /c
|
||||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||||
@@ -109,7 +109,7 @@ LINK32=link.exe
|
|||||||
# PROP Ignore_Export_Lib 0
|
# PROP Ignore_Export_Lib 0
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "WXWINDLL_EXPORTS" /YX /FD /GZ /c
|
# ADD BASE CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "WXWINDLL_EXPORTS" /YX /FD /GZ /c
|
||||||
# ADD CPP /nologo /MTd /W4 /Gm /ZI /Od /I "$(wx)\include" /I "$(wx)\src\zlib" /D "_DEBUG" /D "__WXDEBUG__" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "WXWINDLL_EXPORTS" /D "__WXMSW__" /D "__WIN95__" /D "__WINDOWS__" /D "__WIN32__" /D "WXMAKINGDLL" /Yu"wx/wxprec.h" /FD /GZ /c
|
# ADD CPP /nologo /MTd /W4 /Gm /ZI /Od /I "$(wx)\include" /I "$(wx)\src\zlib" /D "_DEBUG" /D "__WXDEBUG__" /D wxUSE_GUI=1 /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /D "WXWINDLL_EXPORTS" /D "__WXMSW__" /D "__WIN95__" /D "__WINDOWS__" /D "__WIN32__" /D "WXMAKINGDLL" /Yu"wx/wxprec.h" /FD /GZ /c
|
||||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||||
|
@@ -282,7 +282,10 @@ protected:
|
|||||||
#include "wx/stubs/app.h"
|
#include "wx/stubs/app.h"
|
||||||
#endif
|
#endif
|
||||||
#else // !GUI
|
#else // !GUI
|
||||||
typedef wxAppBase wxApp;
|
// can't use typedef because wxApp forward declared as a class
|
||||||
|
class WXDLLEXPORT wxApp : public wxAppBase
|
||||||
|
{
|
||||||
|
};
|
||||||
#endif // GUI/!GUI
|
#endif // GUI/!GUI
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -322,13 +325,13 @@ inline void WXDLLEXPORT wxPostEvent(wxEvtHandler *dest, wxEvent& event)
|
|||||||
dest->AddPendingEvent(event);
|
dest->AddPendingEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // wxUSE_GUI/!wxUSE_GUI
|
#endif // wxUSE_GUI
|
||||||
|
|
||||||
// console applications may avoid using DECLARE_APP and IMPLEMENT_APP macros
|
// console applications may avoid using DECLARE_APP and IMPLEMENT_APP macros
|
||||||
// and call these functions instead at the program startup and termination
|
// and call these functions instead at the program startup and termination
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
#if wxUSE_NOGUI
|
#if !wxUSE_GUI
|
||||||
|
|
||||||
// initialize the library (may be called as many times as needed, but each
|
// initialize the library (may be called as many times as needed, but each
|
||||||
// call to wxInitialize() must be matched by wxUninitialize())
|
// call to wxInitialize() must be matched by wxUninitialize())
|
||||||
@@ -338,7 +341,7 @@ extern bool WXDLLEXPORT wxInitialize();
|
|||||||
// wxUninitialize()
|
// wxUninitialize()
|
||||||
extern void WXDLLEXPORT wxUninitialize();
|
extern void WXDLLEXPORT wxUninitialize();
|
||||||
|
|
||||||
#endif // wxUSE_NOGUI
|
#endif // !wxUSE_GUI
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// macros for dynamic creation of the application object
|
// macros for dynamic creation of the application object
|
||||||
|
@@ -43,6 +43,8 @@ static const double pt2mm = (1/(METRIC_CONVERSION_CONSTANT*72));
|
|||||||
// standard icons from the resources
|
// standard icons from the resources
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if wxUSE_GUI
|
||||||
|
|
||||||
WXDLLEXPORT_DATA(extern HICON) wxSTD_FRAME_ICON;
|
WXDLLEXPORT_DATA(extern HICON) wxSTD_FRAME_ICON;
|
||||||
WXDLLEXPORT_DATA(extern HICON) wxSTD_MDIPARENTFRAME_ICON;
|
WXDLLEXPORT_DATA(extern HICON) wxSTD_MDIPARENTFRAME_ICON;
|
||||||
WXDLLEXPORT_DATA(extern HICON) wxSTD_MDICHILDFRAME_ICON;
|
WXDLLEXPORT_DATA(extern HICON) wxSTD_MDICHILDFRAME_ICON;
|
||||||
@@ -51,6 +53,8 @@ WXDLLEXPORT_DATA(extern HICON) wxDEFAULT_MDIPARENTFRAME_ICON;
|
|||||||
WXDLLEXPORT_DATA(extern HICON) wxDEFAULT_MDICHILDFRAME_ICON;
|
WXDLLEXPORT_DATA(extern HICON) wxDEFAULT_MDICHILDFRAME_ICON;
|
||||||
WXDLLEXPORT_DATA(extern HFONT) wxSTATUS_LINE_FONT;
|
WXDLLEXPORT_DATA(extern HFONT) wxSTATUS_LINE_FONT;
|
||||||
|
|
||||||
|
#endif // wxUSE_GUI
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// define things missing from some compilers' headers
|
// define things missing from some compilers' headers
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -268,9 +272,13 @@ private:
|
|||||||
// global data
|
// global data
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if 0 // where is this??
|
||||||
// The MakeProcInstance version of the function wxSubclassedGenericControlProc
|
// The MakeProcInstance version of the function wxSubclassedGenericControlProc
|
||||||
WXDLLEXPORT_DATA(extern FARPROC) wxGenericControlSubClassProc;
|
WXDLLEXPORT_DATA(extern FARPROC) wxGenericControlSubClassProc;
|
||||||
|
#endif // 0
|
||||||
|
|
||||||
WXDLLEXPORT_DATA(extern wxChar*) wxBuffer;
|
WXDLLEXPORT_DATA(extern wxChar*) wxBuffer;
|
||||||
|
|
||||||
WXDLLEXPORT_DATA(extern HINSTANCE) wxhInstance;
|
WXDLLEXPORT_DATA(extern HINSTANCE) wxhInstance;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -279,11 +287,13 @@ WXDLLEXPORT_DATA(extern HINSTANCE) wxhInstance;
|
|||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
WXDLLEXPORT HINSTANCE wxGetInstance();
|
WXDLLEXPORT HINSTANCE wxGetInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
WXDLLEXPORT void wxSetInstance(HINSTANCE hInst);
|
WXDLLEXPORT void wxSetInstance(HINSTANCE hInst);
|
||||||
|
|
||||||
|
#if wxUSE_GUI
|
||||||
|
|
||||||
WXDLLEXPORT wxWindow* wxFindWinFromHandle(WXHWND hWnd);
|
WXDLLEXPORT wxWindow* wxFindWinFromHandle(WXHWND hWnd);
|
||||||
|
|
||||||
WXDLLEXPORT void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont *the_font);
|
WXDLLEXPORT void wxGetCharSize(WXHWND wnd, int *x, int *y, const wxFont *the_font);
|
||||||
@@ -316,5 +326,7 @@ inline bool wxStyleHasBorder(long style)
|
|||||||
wxSUNKEN_BORDER | wxDOUBLE_BORDER)) != 0;
|
wxSUNKEN_BORDER | wxDOUBLE_BORDER)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_GUI
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
// _WX_PRIVATE_H_
|
// _WX_PRIVATE_H_
|
||||||
|
@@ -187,6 +187,19 @@
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// FindResource
|
||||||
|
#ifdef FindResource
|
||||||
|
#undef FindResource
|
||||||
|
inline HRSRC FindResource(HMODULE hModule, LPCTSTR lpName, LPCTSTR lpType)
|
||||||
|
{
|
||||||
|
#ifdef _UNICODE
|
||||||
|
return FindResourceW(hModule, lpName, lpType);
|
||||||
|
#else
|
||||||
|
return FindResourceA(hModule, lpName, lpType);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// IsMaximized
|
// IsMaximized
|
||||||
|
|
||||||
#ifdef IsMaximized
|
#ifdef IsMaximized
|
||||||
|
@@ -53,9 +53,16 @@ enum wxThreadError
|
|||||||
wxTHREAD_NO_RESOURCE, // No resource left to create a new thread
|
wxTHREAD_NO_RESOURCE, // No resource left to create a new thread
|
||||||
wxTHREAD_RUNNING, // The thread is already running
|
wxTHREAD_RUNNING, // The thread is already running
|
||||||
wxTHREAD_NOT_RUNNING, // The thread isn't running
|
wxTHREAD_NOT_RUNNING, // The thread isn't running
|
||||||
|
wxTHREAD_KILLED, // Thread we waited for had to be killed
|
||||||
wxTHREAD_MISC_ERROR // Some other error
|
wxTHREAD_MISC_ERROR // Some other error
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum wxThreadKind
|
||||||
|
{
|
||||||
|
wxTHREAD_DETACHED,
|
||||||
|
wxTHREAD_JOINABLE
|
||||||
|
};
|
||||||
|
|
||||||
// defines the interval of priority
|
// defines the interval of priority
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@@ -231,15 +238,18 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Thread management class
|
// Thread class
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// FIXME Thread termination model is still unclear. Delete() should probably
|
// there are two different kinds of threads: joinable and detached (default)
|
||||||
// have a timeout after which the thread must be Kill()ed.
|
// ones. Only joinable threads can return a return code and only detached
|
||||||
|
// threads auto-delete themselves - the user should delete the joinable
|
||||||
|
// threads manually.
|
||||||
|
|
||||||
// NB: in the function descriptions the words "this thread" mean the thread
|
// NB: in the function descriptions the words "this thread" mean the thread
|
||||||
// created by the wxThread object while "main thread" is the thread created
|
// created by the wxThread object while "main thread" is the thread created
|
||||||
// during the process initialization (a.k.a. the GUI thread)
|
// during the process initialization (a.k.a. the GUI thread)
|
||||||
|
|
||||||
class wxThreadInternal;
|
class wxThreadInternal;
|
||||||
class WXDLLEXPORT wxThread
|
class WXDLLEXPORT wxThread
|
||||||
{
|
{
|
||||||
@@ -266,34 +276,52 @@ public:
|
|||||||
// NB: at least under MSW worker threads can not call ::wxSleep()!
|
// NB: at least under MSW worker threads can not call ::wxSleep()!
|
||||||
static void Sleep(unsigned long milliseconds);
|
static void Sleep(unsigned long milliseconds);
|
||||||
|
|
||||||
// default constructor
|
// constructor only creates the C++ thread object and doesn't create (or
|
||||||
wxThread();
|
// start) the real thread
|
||||||
|
wxThread(wxThreadKind kind = wxTHREAD_DETACHED);
|
||||||
|
|
||||||
|
// functions that change the thread state: all these can only be called
|
||||||
|
// from _another_ thread (typically the thread that created this one, e.g.
|
||||||
|
// the main thread), not from the thread itself
|
||||||
|
|
||||||
// function that change the thread state
|
|
||||||
// create a new thread - call Run() to start it
|
// create a new thread - call Run() to start it
|
||||||
wxThreadError Create();
|
wxThreadError Create();
|
||||||
|
|
||||||
// starts execution of the thread - from the moment Run() is called the
|
// starts execution of the thread - from the moment Run() is called
|
||||||
// execution of wxThread::Entry() may start at any moment, caller
|
// the execution of wxThread::Entry() may start at any moment, caller
|
||||||
// shouldn't suppose that it starts after (or before) Run() returns.
|
// shouldn't suppose that it starts after (or before) Run() returns.
|
||||||
wxThreadError Run();
|
wxThreadError Run();
|
||||||
|
|
||||||
// stops the thread if it's running and deletes the wxThread object
|
// stops the thread if it's running and deletes the wxThread object if
|
||||||
// freeing its memory. This function should also be called if the
|
// this is a detached thread freeing its memory - otherwise (for
|
||||||
// Create() or Run() fails to free memory (otherwise it will be done by
|
// joinable threads) you still need to delete wxThread object
|
||||||
// the thread itself when it terminates). The return value is the
|
// yourself.
|
||||||
// thread exit code if the thread was gracefully terminated, 0 if it
|
//
|
||||||
// wasn't running and -1 if an error occured.
|
// this function only works if the thread calls TestDestroy()
|
||||||
ExitCode Delete();
|
// periodically - the thread will only be deleted the next time it
|
||||||
|
// does it!
|
||||||
|
//
|
||||||
|
// will fill the rc pointer with the thread exit code if it's !NULL
|
||||||
|
wxThreadError Delete(ExitCode *rc = (ExitCode *)NULL);
|
||||||
|
|
||||||
|
// waits for a joinable thread to finish and returns its exit code
|
||||||
|
//
|
||||||
|
// Returns (ExitCode)-1 on error (for example, if the thread is not
|
||||||
|
// joinable)
|
||||||
|
ExitCode Wait();
|
||||||
|
|
||||||
// kills the thread without giving it any chance to clean up - should
|
// kills the thread without giving it any chance to clean up - should
|
||||||
// not be used in normal circumstances, use Delete() instead. It is a
|
// not be used in normal circumstances, use Delete() instead. It is a
|
||||||
// dangerous function that should only be used in the most extreme
|
// dangerous function that should only be used in the most extreme
|
||||||
// cases! The wxThread object is deleted by Kill() if thread was
|
// cases!
|
||||||
// killed (i.e. no errors occured).
|
//
|
||||||
|
// The wxThread object is deleted by Kill() if the thread is
|
||||||
|
// detachable, but you still have to delete it manually for joinable
|
||||||
|
// threads.
|
||||||
wxThreadError Kill();
|
wxThreadError Kill();
|
||||||
|
|
||||||
// pause a running thread
|
// pause a running thread: as Delete(), this only works if the thread
|
||||||
|
// calls TestDestroy() regularly
|
||||||
wxThreadError Pause();
|
wxThreadError Pause();
|
||||||
|
|
||||||
// resume a paused thread
|
// resume a paused thread
|
||||||
@@ -308,10 +336,6 @@ public:
|
|||||||
// Get the current priority.
|
// Get the current priority.
|
||||||
unsigned int GetPriority() const;
|
unsigned int GetPriority() const;
|
||||||
|
|
||||||
// Get the thread ID - a platform dependent number which uniquely
|
|
||||||
// identifies a thread inside a process
|
|
||||||
unsigned long GetID() const;
|
|
||||||
|
|
||||||
// thread status inquiries
|
// thread status inquiries
|
||||||
// Returns true if the thread is alive: i.e. running or suspended
|
// Returns true if the thread is alive: i.e. running or suspended
|
||||||
bool IsAlive() const;
|
bool IsAlive() const;
|
||||||
@@ -320,11 +344,22 @@ public:
|
|||||||
// Returns true if the thread is suspended
|
// Returns true if the thread is suspended
|
||||||
bool IsPaused() const;
|
bool IsPaused() const;
|
||||||
|
|
||||||
|
// is the thread of detached kind?
|
||||||
|
bool IsDetached() const { return m_isDetached; }
|
||||||
|
|
||||||
|
// Get the thread ID - a platform dependent number which uniquely
|
||||||
|
// identifies a thread inside a process
|
||||||
|
unsigned long GetId() const;
|
||||||
|
|
||||||
// called when the thread exits - in the context of this thread
|
// called when the thread exits - in the context of this thread
|
||||||
//
|
//
|
||||||
// NB: this function will not be called if the thread is Kill()ed
|
// NB: this function will not be called if the thread is Kill()ed
|
||||||
virtual void OnExit() { }
|
virtual void OnExit() { }
|
||||||
|
|
||||||
|
// dtor is public, but the detached threads should never be deleted - use
|
||||||
|
// Delete() instead (or leave the thread terminate by itself)
|
||||||
|
virtual ~wxThread();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Returns TRUE if the thread was asked to terminate: this function should
|
// Returns TRUE if the thread was asked to terminate: this function should
|
||||||
// be called by the thread from time to time, otherwise the main thread
|
// be called by the thread from time to time, otherwise the main thread
|
||||||
@@ -332,14 +367,7 @@ protected:
|
|||||||
bool TestDestroy();
|
bool TestDestroy();
|
||||||
|
|
||||||
// exits from the current thread - can be called only from this thread
|
// exits from the current thread - can be called only from this thread
|
||||||
void Exit(void *exitcode = 0);
|
void Exit(ExitCode exitcode = 0);
|
||||||
|
|
||||||
// destructor is private - user code can't delete thread objects, they will
|
|
||||||
// auto-delete themselves (and thus must be always allocated on the heap).
|
|
||||||
// Use Delete() or Kill() instead.
|
|
||||||
//
|
|
||||||
// NB: derived classes dtors shouldn't be public neither!
|
|
||||||
virtual ~wxThread();
|
|
||||||
|
|
||||||
// entry point for the thread - called by Run() and executes in the context
|
// entry point for the thread - called by Run() and executes in the context
|
||||||
// of this thread.
|
// of this thread.
|
||||||
@@ -357,6 +385,9 @@ private:
|
|||||||
|
|
||||||
// protects access to any methods of wxThreadInternal object
|
// protects access to any methods of wxThreadInternal object
|
||||||
wxCriticalSection m_critsect;
|
wxCriticalSection m_critsect;
|
||||||
|
|
||||||
|
// true if the thread is detached, false if it is joinable
|
||||||
|
bool m_isDetached;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -369,9 +400,9 @@ void WXDLLEXPORT wxMutexGuiLeave();
|
|||||||
|
|
||||||
// macros for entering/leaving critical sections which may be used without
|
// macros for entering/leaving critical sections which may be used without
|
||||||
// having to take them inside "#if wxUSE_THREADS"
|
// having to take them inside "#if wxUSE_THREADS"
|
||||||
#define wxENTER_CRIT_SECT(cs) (cs)->Enter()
|
#define wxENTER_CRIT_SECT(cs) (cs).Enter()
|
||||||
#define wxLEAVE_CRIT_SECT(cs) (cs)->Leave()
|
#define wxLEAVE_CRIT_SECT(cs) (cs).Leave()
|
||||||
#define wxCRIT_SECT_LOCKER(name, cs) wxCriticalSectionLocker name(*cs)
|
#define wxCRIT_SECT_LOCKER(name, cs) wxCriticalSectionLocker name(cs)
|
||||||
|
|
||||||
#else // !wxUSE_THREADS
|
#else // !wxUSE_THREADS
|
||||||
|
|
||||||
|
@@ -172,7 +172,7 @@ WXDLLEXPORT int wxKill(long pid, wxSignal sig = wxSIGTERM);
|
|||||||
// If no command then just the shell
|
// If no command then just the shell
|
||||||
WXDLLEXPORT bool wxShell(const wxString& command = wxEmptyString);
|
WXDLLEXPORT bool wxShell(const wxString& command = wxEmptyString);
|
||||||
|
|
||||||
// Sleep for nSecs seconds under UNIX, do nothing under Windows
|
// Sleep for nSecs seconds
|
||||||
WXDLLEXPORT void wxSleep(int nSecs);
|
WXDLLEXPORT void wxSleep(int nSecs);
|
||||||
|
|
||||||
// Sleep for a given amount of milliseconds
|
// Sleep for a given amount of milliseconds
|
||||||
|
@@ -30,8 +30,8 @@
|
|||||||
// what to test?
|
// what to test?
|
||||||
|
|
||||||
//#define TEST_ARRAYS
|
//#define TEST_ARRAYS
|
||||||
#define TEST_LOG
|
//#define TEST_LOG
|
||||||
//#define TEST_THREADS
|
#define TEST_THREADS
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// implementation
|
// implementation
|
||||||
@@ -47,30 +47,51 @@
|
|||||||
|
|
||||||
static size_t gs_counter = (size_t)-1;
|
static size_t gs_counter = (size_t)-1;
|
||||||
static wxCriticalSection gs_critsect;
|
static wxCriticalSection gs_critsect;
|
||||||
|
static wxCondition gs_cond;
|
||||||
|
|
||||||
class MyThread : public wxThread
|
class MyJoinableThread : public wxThread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MyThread(char ch);
|
MyJoinableThread(size_t n) : wxThread(wxTHREAD_JOINABLE)
|
||||||
|
{ m_n = n; Create(); }
|
||||||
|
|
||||||
// thread execution starts here
|
// thread execution starts here
|
||||||
virtual void *Entry();
|
virtual ExitCode Entry();
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t m_n;
|
||||||
|
};
|
||||||
|
|
||||||
|
wxThread::ExitCode MyJoinableThread::Entry()
|
||||||
|
{
|
||||||
|
unsigned long res = 1;
|
||||||
|
for ( size_t n = 1; n < m_n; n++ )
|
||||||
|
{
|
||||||
|
res *= n;
|
||||||
|
|
||||||
|
// it's a loooong calculation :-)
|
||||||
|
Sleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (ExitCode)res;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyDetachedThread : public wxThread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MyDetachedThread(char ch) { m_ch = ch; Create(); }
|
||||||
|
|
||||||
|
// thread execution starts here
|
||||||
|
virtual ExitCode Entry();
|
||||||
|
|
||||||
// and stops here
|
// and stops here
|
||||||
virtual void OnExit();
|
virtual void OnExit();
|
||||||
|
|
||||||
public:
|
private:
|
||||||
char m_ch;
|
char m_ch;
|
||||||
};
|
};
|
||||||
|
|
||||||
MyThread::MyThread(char ch)
|
wxThread::ExitCode MyDetachedThread::Entry()
|
||||||
{
|
|
||||||
m_ch = ch;
|
|
||||||
|
|
||||||
Create();
|
|
||||||
}
|
|
||||||
|
|
||||||
void *MyThread::Entry()
|
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker lock(gs_critsect);
|
wxCriticalSectionLocker lock(gs_critsect);
|
||||||
@@ -80,7 +101,8 @@ void *MyThread::Entry()
|
|||||||
gs_counter++;
|
gs_counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( size_t n = 0; n < 10; n++ )
|
static const size_t nIter = 10;
|
||||||
|
for ( size_t n = 0; n < nIter; n++ )
|
||||||
{
|
{
|
||||||
if ( TestDestroy() )
|
if ( TestDestroy() )
|
||||||
break;
|
break;
|
||||||
@@ -91,13 +113,14 @@ void *MyThread::Entry()
|
|||||||
wxThread::Sleep(100);
|
wxThread::Sleep(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyThread::OnExit()
|
void MyDetachedThread::OnExit()
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker lock(gs_critsect);
|
wxCriticalSectionLocker lock(gs_critsect);
|
||||||
gs_counter--;
|
if ( !--gs_counter )
|
||||||
|
gs_cond.Signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TEST_THREADS
|
#endif // TEST_THREADS
|
||||||
@@ -178,33 +201,44 @@ int main(int argc, char **argv)
|
|||||||
printf(msg);
|
printf(msg);
|
||||||
|
|
||||||
// but this one will because log functions use fixed size buffer
|
// but this one will because log functions use fixed size buffer
|
||||||
wxLogMessage("A very very long message 2: '%s', the end!\n", s.c_str());
|
// (note that it doesn't need '\n' at the end neither - will be added
|
||||||
|
// by wxLog anyhow)
|
||||||
|
wxLogMessage("A very very long message 2: '%s', the end!", s.c_str());
|
||||||
#endif // TEST_LOG
|
#endif // TEST_LOG
|
||||||
|
|
||||||
#ifdef TEST_THREADS
|
#ifdef TEST_THREADS
|
||||||
|
puts("Testing detached threads...");
|
||||||
|
|
||||||
static const size_t nThreads = 3;
|
static const size_t nThreads = 3;
|
||||||
MyThread *threads[nThreads];
|
MyDetachedThread *threads[nThreads];
|
||||||
size_t n;
|
size_t n;
|
||||||
for ( n = 0; n < nThreads; n++ )
|
for ( n = 0; n < nThreads; n++ )
|
||||||
{
|
{
|
||||||
threads[n] = new MyThread('+' + n);
|
threads[n] = new MyDetachedThread('A' + n);
|
||||||
|
}
|
||||||
|
|
||||||
|
threads[0]->SetPriority(WXTHREAD_MIN_PRIORITY);
|
||||||
|
threads[1]->SetPriority(WXTHREAD_MAX_PRIORITY);
|
||||||
|
|
||||||
|
for ( n = 0; n < nThreads; n++ )
|
||||||
|
{
|
||||||
threads[n]->Run();
|
threads[n]->Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait until all threads terminate
|
// wait until all threads terminate
|
||||||
for ( ;; )
|
wxMutex mutex;
|
||||||
{
|
mutex.Lock();
|
||||||
wxCriticalSectionLocker lock(gs_critsect);
|
gs_cond.Wait(mutex);
|
||||||
if ( !gs_counter )
|
mutex.Unlock();
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
puts("\nThat's all, folks!");
|
puts("\n\nTesting a joinable thread used for a loooong calculation...");
|
||||||
|
|
||||||
for ( n = 0; n < nThreads; n++ )
|
// calc 10! in the background
|
||||||
{
|
MyJoinableThread thread(10);
|
||||||
threads[n]->Delete();
|
thread.Run();
|
||||||
}
|
|
||||||
|
printf("\nThread terminated with exit code %lu.\n",
|
||||||
|
(unsigned long)thread.Wait());
|
||||||
#endif // TEST_THREADS
|
#endif // TEST_THREADS
|
||||||
|
|
||||||
wxUninitialize();
|
wxUninitialize();
|
||||||
|
@@ -150,7 +150,7 @@ void *MyThread::Entry()
|
|||||||
wxString text;
|
wxString text;
|
||||||
|
|
||||||
text.Printf("Thread 0x%x started (priority = %d).\n",
|
text.Printf("Thread 0x%x started (priority = %d).\n",
|
||||||
GetID(), GetPriority());
|
GetId(), GetPriority());
|
||||||
WriteText(text);
|
WriteText(text);
|
||||||
|
|
||||||
for ( m_count = 0; m_count < 10; m_count++ )
|
for ( m_count = 0; m_count < 10; m_count++ )
|
||||||
@@ -159,14 +159,14 @@ void *MyThread::Entry()
|
|||||||
if ( TestDestroy() )
|
if ( TestDestroy() )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
text.Printf("[%u] Thread 0x%x here.\n", m_count, GetID());
|
text.Printf("[%u] Thread 0x%x here.\n", m_count, GetId());
|
||||||
WriteText(text);
|
WriteText(text);
|
||||||
|
|
||||||
// wxSleep() can't be called from non-GUI thread!
|
// wxSleep() can't be called from non-GUI thread!
|
||||||
wxThread::Sleep(1000);
|
wxThread::Sleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
text.Printf("Thread 0x%x finished.\n", GetID());
|
text.Printf("Thread 0x%x finished.\n", GetId());
|
||||||
WriteText(text);
|
WriteText(text);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -266,17 +266,18 @@ MyThread *MyFrame::CreateThread()
|
|||||||
|
|
||||||
void MyFrame::OnStartThreads(wxCommandEvent& WXUNUSED(event) )
|
void MyFrame::OnStartThreads(wxCommandEvent& WXUNUSED(event) )
|
||||||
{
|
{
|
||||||
static wxString s_str;
|
static long s_num = 10;
|
||||||
s_str = wxGetTextFromUser("How many threads to start: ",
|
|
||||||
"wxThread sample",
|
s_num = wxGetNumberFromUser("How many threads to start: ", "",
|
||||||
s_str, this);
|
"wxThread sample", s_num, 1, 10000, this);
|
||||||
if ( s_str.IsEmpty() )
|
if ( s_num == -1 )
|
||||||
return;
|
{
|
||||||
|
s_num = 10;
|
||||||
|
|
||||||
size_t count, n;
|
|
||||||
sscanf(s_str, "%u", &count);
|
|
||||||
if ( count == 0 )
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t count = (size_t)s_num, n;
|
||||||
|
|
||||||
wxArrayThread threads;
|
wxArrayThread threads;
|
||||||
|
|
||||||
|
@@ -47,7 +47,7 @@
|
|||||||
void wxAppBase::ProcessPendingEvents()
|
void wxAppBase::ProcessPendingEvents()
|
||||||
{
|
{
|
||||||
// ensure that we're the only thread to modify the pending events list
|
// ensure that we're the only thread to modify the pending events list
|
||||||
wxCRIT_SECT_LOCKER(locker, wxPendingEventsLocker);
|
wxCRIT_SECT_LOCKER(locker, *wxPendingEventsLocker);
|
||||||
|
|
||||||
if ( !wxPendingEvents )
|
if ( !wxPendingEvents )
|
||||||
return;
|
return;
|
||||||
|
@@ -609,13 +609,13 @@ void wxEvtHandler::AddPendingEvent(wxEvent& event)
|
|||||||
|
|
||||||
m_pendingEvents->Append(event2);
|
m_pendingEvents->Append(event2);
|
||||||
|
|
||||||
wxENTER_CRIT_SECT(wxPendingEventsLocker);
|
wxENTER_CRIT_SECT(*wxPendingEventsLocker);
|
||||||
|
|
||||||
if ( !wxPendingEvents )
|
if ( !wxPendingEvents )
|
||||||
wxPendingEvents = new wxList;
|
wxPendingEvents = new wxList;
|
||||||
wxPendingEvents->Append(this);
|
wxPendingEvents->Append(this);
|
||||||
|
|
||||||
wxLEAVE_CRIT_SECT(wxPendingEventsLocker);
|
wxLEAVE_CRIT_SECT(*wxPendingEventsLocker);
|
||||||
|
|
||||||
wxWakeUpIdle();
|
wxWakeUpIdle();
|
||||||
}
|
}
|
||||||
@@ -623,9 +623,9 @@ void wxEvtHandler::AddPendingEvent(wxEvent& event)
|
|||||||
void wxEvtHandler::ProcessPendingEvents()
|
void wxEvtHandler::ProcessPendingEvents()
|
||||||
{
|
{
|
||||||
#if defined(__VISAGECPP__)
|
#if defined(__VISAGECPP__)
|
||||||
wxCRIT_SECT_LOCKER(locker, &m_eventsLocker);
|
|
||||||
#else
|
|
||||||
wxCRIT_SECT_LOCKER(locker, m_eventsLocker);
|
wxCRIT_SECT_LOCKER(locker, m_eventsLocker);
|
||||||
|
#else
|
||||||
|
wxCRIT_SECT_LOCKER(locker, *m_eventsLocker);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
wxNode *node = m_pendingEvents->First();
|
wxNode *node = m_pendingEvents->First();
|
||||||
|
@@ -30,7 +30,6 @@
|
|||||||
|
|
||||||
#include "wx/module.h"
|
#include "wx/module.h"
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// global vars
|
// global vars
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@@ -48,6 +48,7 @@
|
|||||||
#include "wx/utils.h"
|
#include "wx/utils.h"
|
||||||
#include "wx/wxchar.h"
|
#include "wx/wxchar.h"
|
||||||
#include "wx/log.h"
|
#include "wx/log.h"
|
||||||
|
#include "wx/thread.h"
|
||||||
|
|
||||||
// other standard headers
|
// other standard headers
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@@ -55,9 +56,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
#include <windows.h>
|
#include "wx/msw/private.h" // includes windows.h for OutputDebugString
|
||||||
// Redefines OutputDebugString if necessary
|
|
||||||
#include "wx/msw/private.h"
|
|
||||||
#else //Unix
|
#else //Unix
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#endif //Win/Unix
|
#endif //Win/Unix
|
||||||
@@ -78,23 +77,36 @@
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// implementation of Log functions
|
// globals
|
||||||
//
|
|
||||||
// NB: unfortunately we need all these distinct functions, we can't make them
|
|
||||||
// macros and not all compilers inline vararg functions.
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// log functions can't allocate memory (LogError("out of memory...") should
|
// log functions can't allocate memory (LogError("out of memory...") should
|
||||||
// work!), so we use a static buffer for all log messages
|
// work!), so we use a static buffer for all log messages
|
||||||
#define LOG_BUFFER_SIZE (4096)
|
#define LOG_BUFFER_SIZE (4096)
|
||||||
|
|
||||||
// static buffer for error messages (FIXME MT-unsafe)
|
// static buffer for error messages
|
||||||
static wxChar s_szBuf[LOG_BUFFER_SIZE];
|
static wxChar s_szBuf[LOG_BUFFER_SIZE];
|
||||||
|
|
||||||
|
#if wxUSE_THREADS
|
||||||
|
|
||||||
|
// the critical section protecting the static buffer
|
||||||
|
static wxCriticalSection gs_csLogBuf;
|
||||||
|
|
||||||
|
#endif // wxUSE_THREADS
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// implementation of Log functions
|
||||||
|
//
|
||||||
|
// NB: unfortunately we need all these distinct functions, we can't make them
|
||||||
|
// macros and not all compilers inline vararg functions.
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// generic log function
|
// generic log function
|
||||||
void wxLogGeneric(wxLogLevel level, const wxChar *szFormat, ...)
|
void wxLogGeneric(wxLogLevel level, const wxChar *szFormat, ...)
|
||||||
{
|
{
|
||||||
if ( wxLog::GetActiveTarget() != NULL ) {
|
if ( wxLog::GetActiveTarget() != NULL ) {
|
||||||
|
wxCRIT_SECT_LOCKER(locker, gs_csLogBuf);
|
||||||
|
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
va_start(argptr, szFormat);
|
va_start(argptr, szFormat);
|
||||||
wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr);
|
wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr);
|
||||||
@@ -108,6 +120,8 @@ void wxLogGeneric(wxLogLevel level, const wxChar *szFormat, ...)
|
|||||||
void wxLog##level(const wxChar *szFormat, ...) \
|
void wxLog##level(const wxChar *szFormat, ...) \
|
||||||
{ \
|
{ \
|
||||||
if ( wxLog::GetActiveTarget() != NULL ) { \
|
if ( wxLog::GetActiveTarget() != NULL ) { \
|
||||||
|
wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); \
|
||||||
|
\
|
||||||
va_list argptr; \
|
va_list argptr; \
|
||||||
va_start(argptr, szFormat); \
|
va_start(argptr, szFormat); \
|
||||||
wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); \
|
wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); \
|
||||||
@@ -129,6 +143,8 @@ void wxLogVerbose(const wxChar *szFormat, ...)
|
|||||||
{
|
{
|
||||||
wxLog *pLog = wxLog::GetActiveTarget();
|
wxLog *pLog = wxLog::GetActiveTarget();
|
||||||
if ( pLog != NULL && pLog->GetVerbose() ) {
|
if ( pLog != NULL && pLog->GetVerbose() ) {
|
||||||
|
wxCRIT_SECT_LOCKER(locker, gs_csLogBuf);
|
||||||
|
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
va_start(argptr, szFormat);
|
va_start(argptr, szFormat);
|
||||||
wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr);
|
wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr);
|
||||||
@@ -144,6 +160,8 @@ void wxLogVerbose(const wxChar *szFormat, ...)
|
|||||||
void wxLog##level(const wxChar *szFormat, ...) \
|
void wxLog##level(const wxChar *szFormat, ...) \
|
||||||
{ \
|
{ \
|
||||||
if ( wxLog::GetActiveTarget() != NULL ) { \
|
if ( wxLog::GetActiveTarget() != NULL ) { \
|
||||||
|
wxCRIT_SECT_LOCKER(locker, gs_csLogBuf); \
|
||||||
|
\
|
||||||
va_list argptr; \
|
va_list argptr; \
|
||||||
va_start(argptr, szFormat); \
|
va_start(argptr, szFormat); \
|
||||||
wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); \
|
wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr); \
|
||||||
@@ -158,6 +176,8 @@ void wxLogVerbose(const wxChar *szFormat, ...)
|
|||||||
wxLog *pLog = wxLog::GetActiveTarget();
|
wxLog *pLog = wxLog::GetActiveTarget();
|
||||||
|
|
||||||
if ( pLog != NULL && wxLog::IsAllowedTraceMask(mask) ) {
|
if ( pLog != NULL && wxLog::IsAllowedTraceMask(mask) ) {
|
||||||
|
wxCRIT_SECT_LOCKER(locker, gs_csLogBuf);
|
||||||
|
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
va_start(argptr, szFormat);
|
va_start(argptr, szFormat);
|
||||||
wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr);
|
wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr);
|
||||||
@@ -175,6 +195,8 @@ void wxLogVerbose(const wxChar *szFormat, ...)
|
|||||||
// that wxLogTrace(wxTraceRefCount | wxTraceOle) will only do something
|
// that wxLogTrace(wxTraceRefCount | wxTraceOle) will only do something
|
||||||
// if both bits are set.
|
// if both bits are set.
|
||||||
if ( pLog != NULL && ((pLog->GetTraceMask() & mask) == mask) ) {
|
if ( pLog != NULL && ((pLog->GetTraceMask() & mask) == mask) ) {
|
||||||
|
wxCRIT_SECT_LOCKER(locker, gs_csLogBuf);
|
||||||
|
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
va_start(argptr, szFormat);
|
va_start(argptr, szFormat);
|
||||||
wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr);
|
wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr);
|
||||||
@@ -207,6 +229,8 @@ void wxLogSysErrorHelper(long lErrCode)
|
|||||||
|
|
||||||
void WXDLLEXPORT wxLogSysError(const wxChar *szFormat, ...)
|
void WXDLLEXPORT wxLogSysError(const wxChar *szFormat, ...)
|
||||||
{
|
{
|
||||||
|
wxCRIT_SECT_LOCKER(locker, gs_csLogBuf);
|
||||||
|
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
va_start(argptr, szFormat);
|
va_start(argptr, szFormat);
|
||||||
wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr);
|
wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr);
|
||||||
@@ -217,6 +241,8 @@ void WXDLLEXPORT wxLogSysError(const wxChar *szFormat, ...)
|
|||||||
|
|
||||||
void WXDLLEXPORT wxLogSysError(long lErrCode, const wxChar *szFormat, ...)
|
void WXDLLEXPORT wxLogSysError(long lErrCode, const wxChar *szFormat, ...)
|
||||||
{
|
{
|
||||||
|
wxCRIT_SECT_LOCKER(locker, gs_csLogBuf);
|
||||||
|
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
va_start(argptr, szFormat);
|
va_start(argptr, szFormat);
|
||||||
wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr);
|
wxVsnprintf(s_szBuf, WXSIZEOF(s_szBuf), szFormat, argptr);
|
||||||
@@ -361,15 +387,16 @@ void wxLogStderr::DoLogString(const wxChar *szString, time_t WXUNUSED(t))
|
|||||||
{
|
{
|
||||||
wxString str;
|
wxString str;
|
||||||
TimeStamp(&str);
|
TimeStamp(&str);
|
||||||
str << szString << wxT('\n');
|
str << szString;
|
||||||
|
|
||||||
fputs(str.mb_str(), m_fp);
|
fputs(str.mb_str(), m_fp);
|
||||||
|
fputc(_T('\n'), m_fp);
|
||||||
fflush(m_fp);
|
fflush(m_fp);
|
||||||
|
|
||||||
// under Windows, programs usually don't have stderr at all, so show the
|
// under Windows, programs usually don't have stderr at all, so show the
|
||||||
// messages also under debugger
|
// messages also under debugger - unless it's a console program
|
||||||
#ifdef __WXMSW__
|
#if defined(__WXMSW__) && wxUSE_GUI
|
||||||
OutputDebugString(str + wxT('\r'));
|
OutputDebugString(str + wxT("\r\n"));
|
||||||
#endif // MSW
|
#endif // MSW
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -771,6 +771,7 @@ bool wxFileTypeImpl::GetMimeType(wxString *mimeType) const
|
|||||||
|
|
||||||
bool wxFileTypeImpl::GetIcon(wxIcon *icon) const
|
bool wxFileTypeImpl::GetIcon(wxIcon *icon) const
|
||||||
{
|
{
|
||||||
|
#if wxUSE_GUI
|
||||||
if ( m_info ) {
|
if ( m_info ) {
|
||||||
// we don't have icons in the fallback resources
|
// we don't have icons in the fallback resources
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -819,6 +820,8 @@ bool wxFileTypeImpl::GetIcon(wxIcon *icon) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// no such file type or no value or incorrect icon entry
|
// no such file type or no value or incorrect icon entry
|
||||||
|
#endif // wxUSE_GUI
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -200,7 +200,12 @@ extern int WXDLLEXPORT wxVsnprintf(wxChar *buf, size_t len,
|
|||||||
|
|
||||||
return iLen;
|
return iLen;
|
||||||
#else // ANSI
|
#else // ANSI
|
||||||
return wxVsnprintfA(buf, len, format, argptr);
|
// vsnprintf() will not terminate the string with '\0' if there is not
|
||||||
|
// enough place, but we want the string to always be NUL terminated
|
||||||
|
int rc = wxVsnprintfA(buf, len - 1, format, argptr);
|
||||||
|
buf[len] = 0;
|
||||||
|
|
||||||
|
return rc;
|
||||||
#endif // Unicode/ANSI
|
#endif // Unicode/ANSI
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -100,7 +100,6 @@ extern wxList WXDLLEXPORT wxPendingDelete;
|
|||||||
extern void wxSetKeyboardHook(bool doIt);
|
extern void wxSetKeyboardHook(bool doIt);
|
||||||
extern wxCursor *g_globalCursor;
|
extern wxCursor *g_globalCursor;
|
||||||
|
|
||||||
HINSTANCE wxhInstance = 0;
|
|
||||||
MSG s_currentMsg;
|
MSG s_currentMsg;
|
||||||
wxApp *wxTheApp = NULL;
|
wxApp *wxTheApp = NULL;
|
||||||
|
|
||||||
@@ -1217,11 +1216,16 @@ void wxWakeUpIdle()
|
|||||||
{
|
{
|
||||||
// Send the top window a dummy message so idle handler processing will
|
// Send the top window a dummy message so idle handler processing will
|
||||||
// start up again. Doing it this way ensures that the idle handler
|
// start up again. Doing it this way ensures that the idle handler
|
||||||
// wakes up in the right thread.
|
// wakes up in the right thread (see also wxWakeUpMainThread() which does
|
||||||
|
// the same for the main app thread only)
|
||||||
wxWindow *topWindow = wxTheApp->GetTopWindow();
|
wxWindow *topWindow = wxTheApp->GetTopWindow();
|
||||||
if ( topWindow ) {
|
if ( topWindow )
|
||||||
HWND hWnd = (HWND)topWindow->GetHWND();
|
{
|
||||||
::PostMessage(hWnd, WM_NULL, 0, 0);
|
if ( !::PostMessage(GetHwndOf(topWindow), WM_NULL, 0, 0) )
|
||||||
|
{
|
||||||
|
// should never happen
|
||||||
|
wxLogLastError("PostMessage(WM_NULL)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1250,17 +1254,6 @@ wxApp::GetStdIcon(int which) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HINSTANCE wxGetInstance()
|
|
||||||
{
|
|
||||||
return wxhInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxSetInstance(HINSTANCE hInst)
|
|
||||||
{
|
|
||||||
wxhInstance = hInst;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For some reason, with MSVC++ 1.5, WinMain isn't linked in properly
|
// For some reason, with MSVC++ 1.5, WinMain isn't linked in properly
|
||||||
// if in a separate file. So include it here to ensure it's linked.
|
// if in a separate file. So include it here to ensure it's linked.
|
||||||
#if (defined(__VISUALC__) && !defined(__WIN32__)) || (defined(__GNUWIN32__) && !defined(__TWIN32__))
|
#if (defined(__VISUALC__) && !defined(__WIN32__)) || (defined(__GNUWIN32__) && !defined(__TWIN32__))
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// Name: main.cpp
|
// Name: msw/main.cpp
|
||||||
// Purpose: Main/DllMain
|
// Purpose: Main/DllMain
|
||||||
// Author: Julian Smart
|
// Author: Julian Smart
|
||||||
// Modified by:
|
// Modified by:
|
||||||
@@ -9,28 +9,51 @@
|
|||||||
// Licence: wxWindows license
|
// Licence: wxWindows license
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// declarations
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// headers
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifdef __GNUG__
|
#ifdef __GNUG__
|
||||||
#pragma implementation
|
#pragma implementation
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// For compilers that support precompilation, includes "wx.h".
|
// For compilers that support precompilation, includes "wx.h".
|
||||||
#include "wx/wxprec.h"
|
#include "wx/wxprec.h"
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
#ifdef __BORLANDC__
|
||||||
#pragma hdrstop
|
#pragma hdrstop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/event.h"
|
#include "wx/event.h"
|
||||||
#include "wx/app.h"
|
#include "wx/app.h"
|
||||||
#include <windows.h>
|
|
||||||
|
#include "wx/msw/private.h"
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// globals
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HINSTANCE wxhInstance = 0;
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// implementation
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// various entry points
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// May wish not to have a DllMain or WinMain, e.g. if we're programming
|
// May wish not to have a DllMain or WinMain, e.g. if we're programming
|
||||||
// a Netscape plugin.
|
// a Netscape plugin or if we're writing a console application
|
||||||
#ifndef NOMAIN
|
#if wxUSE_GUI && !defined(NOMAIN)
|
||||||
|
|
||||||
// NT defines APIENTRY, 3.x not
|
// NT defines APIENTRY, 3.x not
|
||||||
#if !defined(APIENTRY)
|
#if !defined(APIENTRY)
|
||||||
#define APIENTRY FAR PASCAL
|
#define APIENTRY FAR PASCAL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -96,7 +119,21 @@ BOOL WINAPI DllMain (HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif // _WINDLL
|
||||||
|
|
||||||
#endif
|
#endif // !NOMAIN
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// global functions
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
HINSTANCE wxGetInstance()
|
||||||
|
{
|
||||||
|
return wxhInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxSetInstance(HINSTANCE hInst)
|
||||||
|
{
|
||||||
|
wxhInstance = hInst;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -160,13 +160,25 @@ void wxRegConfig::SetPath(const wxString& strPath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// recombine path parts in one variable
|
// recombine path parts in one variable
|
||||||
wxString strRegPath;
|
wxString strOldPath = m_strPath, strRegPath;
|
||||||
m_strPath.Empty();
|
m_strPath.Empty();
|
||||||
for ( size_t n = 0; n < aParts.Count(); n++ ) {
|
for ( size_t n = 0; n < aParts.Count(); n++ ) {
|
||||||
strRegPath << '\\' << aParts[n];
|
strRegPath << '\\' << aParts[n];
|
||||||
m_strPath << wxCONFIG_PATH_SEPARATOR << aParts[n];
|
m_strPath << wxCONFIG_PATH_SEPARATOR << aParts[n];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( m_strPath == strOldPath )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// as we create the registry key when SetPath(key) is done, we can be left
|
||||||
|
// with plenty of empty keys if this was only done to try to read some value
|
||||||
|
// which, in fact, doesn't exist - to prevent this from happening we
|
||||||
|
// automatically delete the old key if it was empty
|
||||||
|
if ( m_keyLocal.IsEmpty() )
|
||||||
|
{
|
||||||
|
m_keyLocal.DeleteSelf();
|
||||||
|
}
|
||||||
|
|
||||||
// change current key(s)
|
// change current key(s)
|
||||||
m_keyLocal.SetName(m_keyLocalRoot, strRegPath);
|
m_keyLocal.SetName(m_keyLocalRoot, strRegPath);
|
||||||
m_keyGlobal.SetName(m_keyGlobalRoot, strRegPath);
|
m_keyGlobal.SetName(m_keyGlobalRoot, strRegPath);
|
||||||
|
@@ -36,6 +36,19 @@
|
|||||||
#include "wx/module.h"
|
#include "wx/module.h"
|
||||||
#include "wx/thread.h"
|
#include "wx/thread.h"
|
||||||
|
|
||||||
|
// must have this symbol defined to get _beginthread/_endthread declarations
|
||||||
|
#ifndef _MT
|
||||||
|
#define _MT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __VISUALC__
|
||||||
|
#include <process.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// constants
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// the possible states of the thread ("=>" shows all possible transitions from
|
// the possible states of the thread ("=>" shows all possible transitions from
|
||||||
// this state)
|
// this state)
|
||||||
enum wxThreadState
|
enum wxThreadState
|
||||||
@@ -48,32 +61,32 @@ enum wxThreadState
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// static variables
|
// this module globals
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// TLS index of the slot where we store the pointer to the current thread
|
// TLS index of the slot where we store the pointer to the current thread
|
||||||
static DWORD s_tlsThisThread = 0xFFFFFFFF;
|
static DWORD gs_tlsThisThread = 0xFFFFFFFF;
|
||||||
|
|
||||||
// id of the main thread - the one which can call GUI functions without first
|
// id of the main thread - the one which can call GUI functions without first
|
||||||
// calling wxMutexGuiEnter()
|
// calling wxMutexGuiEnter()
|
||||||
static DWORD s_idMainThread = 0;
|
static DWORD gs_idMainThread = 0;
|
||||||
|
|
||||||
// if it's FALSE, some secondary thread is holding the GUI lock
|
// if it's FALSE, some secondary thread is holding the GUI lock
|
||||||
static bool s_bGuiOwnedByMainThread = TRUE;
|
static bool gs_bGuiOwnedByMainThread = TRUE;
|
||||||
|
|
||||||
// critical section which controls access to all GUI functions: any secondary
|
// critical section which controls access to all GUI functions: any secondary
|
||||||
// thread (i.e. except the main one) must enter this crit section before doing
|
// thread (i.e. except the main one) must enter this crit section before doing
|
||||||
// any GUI calls
|
// any GUI calls
|
||||||
static wxCriticalSection *s_critsectGui = NULL;
|
static wxCriticalSection *gs_critsectGui = NULL;
|
||||||
|
|
||||||
// critical section which protects s_nWaitingForGui variable
|
// critical section which protects gs_nWaitingForGui variable
|
||||||
static wxCriticalSection *s_critsectWaitingForGui = NULL;
|
static wxCriticalSection *gs_critsectWaitingForGui = NULL;
|
||||||
|
|
||||||
// number of threads waiting for GUI in wxMutexGuiEnter()
|
// number of threads waiting for GUI in wxMutexGuiEnter()
|
||||||
static size_t s_nWaitingForGui = 0;
|
static size_t gs_nWaitingForGui = 0;
|
||||||
|
|
||||||
// are we waiting for a thread termination?
|
// are we waiting for a thread termination?
|
||||||
static bool s_waitingForThread = FALSE;
|
static bool gs_waitingForThread = FALSE;
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Windows implementation of thread classes
|
// Windows implementation of thread classes
|
||||||
@@ -169,6 +182,46 @@ wxMutexError wxMutex::Unlock()
|
|||||||
class wxConditionInternal
|
class wxConditionInternal
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
wxConditionInternal()
|
||||||
|
{
|
||||||
|
event = ::CreateEvent(
|
||||||
|
NULL, // default secutiry
|
||||||
|
FALSE, // not manual reset
|
||||||
|
FALSE, // nonsignaled initially
|
||||||
|
NULL // nameless event
|
||||||
|
);
|
||||||
|
if ( !event )
|
||||||
|
{
|
||||||
|
wxLogSysError(_("Can not create event object."));
|
||||||
|
}
|
||||||
|
waiters = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Wait(wxMutex& mutex, DWORD timeout)
|
||||||
|
{
|
||||||
|
mutex.Unlock();
|
||||||
|
waiters++;
|
||||||
|
|
||||||
|
// FIXME this should be MsgWaitForMultipleObjects() as well probably
|
||||||
|
DWORD rc = ::WaitForSingleObject(event, timeout);
|
||||||
|
|
||||||
|
waiters--;
|
||||||
|
mutex.Lock();
|
||||||
|
|
||||||
|
return rc != WAIT_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
~wxConditionInternal()
|
||||||
|
{
|
||||||
|
if ( event )
|
||||||
|
{
|
||||||
|
if ( !::CloseHandle(event) )
|
||||||
|
{
|
||||||
|
wxLogLastError("CloseHandle(event)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
HANDLE event;
|
HANDLE event;
|
||||||
int waiters;
|
int waiters;
|
||||||
};
|
};
|
||||||
@@ -176,59 +229,46 @@ public:
|
|||||||
wxCondition::wxCondition()
|
wxCondition::wxCondition()
|
||||||
{
|
{
|
||||||
p_internal = new wxConditionInternal;
|
p_internal = new wxConditionInternal;
|
||||||
p_internal->event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
|
||||||
if ( !p_internal->event )
|
|
||||||
{
|
|
||||||
wxLogSysError(_("Can not create event object."));
|
|
||||||
}
|
|
||||||
|
|
||||||
p_internal->waiters = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxCondition::~wxCondition()
|
wxCondition::~wxCondition()
|
||||||
{
|
{
|
||||||
CloseHandle(p_internal->event);
|
delete p_internal;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxCondition::Wait(wxMutex& mutex)
|
void wxCondition::Wait(wxMutex& mutex)
|
||||||
{
|
{
|
||||||
mutex.Unlock();
|
(void)p_internal->Wait(mutex, INFINITE);
|
||||||
p_internal->waiters++;
|
|
||||||
WaitForSingleObject(p_internal->event, INFINITE);
|
|
||||||
p_internal->waiters--;
|
|
||||||
mutex.Lock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxCondition::Wait(wxMutex& mutex,
|
bool wxCondition::Wait(wxMutex& mutex,
|
||||||
unsigned long sec,
|
unsigned long sec,
|
||||||
unsigned long nsec)
|
unsigned long nsec)
|
||||||
{
|
{
|
||||||
DWORD ret;
|
return p_internal->Wait(mutex, sec*1000 + nsec/1000000);
|
||||||
|
|
||||||
mutex.Unlock();
|
|
||||||
p_internal->waiters++;
|
|
||||||
ret = WaitForSingleObject(p_internal->event, (sec*1000)+(nsec/1000000));
|
|
||||||
p_internal->waiters--;
|
|
||||||
mutex.Lock();
|
|
||||||
|
|
||||||
return (ret != WAIT_TIMEOUT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxCondition::Signal()
|
void wxCondition::Signal()
|
||||||
{
|
{
|
||||||
SetEvent(p_internal->event);
|
// set the event to signaled: if a thread is already waiting on it, it will
|
||||||
|
// be woken up, otherwise the event will remain in the signaled state until
|
||||||
|
// someone waits on it. In any case, the system will return it to a non
|
||||||
|
// signalled state afterwards. If multiple threads are waiting, only one
|
||||||
|
// will be woken up.
|
||||||
|
if ( !::SetEvent(p_internal->event) )
|
||||||
|
{
|
||||||
|
wxLogLastError("SetEvent");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxCondition::Broadcast()
|
void wxCondition::Broadcast()
|
||||||
{
|
{
|
||||||
int i;
|
// this works because all these threads are already waiting and so each
|
||||||
|
// SetEvent() inside Signal() is really a PulseEvent() because the event
|
||||||
for (i=0;i<p_internal->waiters;i++)
|
// state is immediately returned to non-signaled
|
||||||
|
for ( int i = 0; i < p_internal->waiters; i++ )
|
||||||
{
|
{
|
||||||
if ( SetEvent(p_internal->event) == 0 )
|
Signal();
|
||||||
{
|
|
||||||
wxLogSysError(_("Couldn't change the state of event object."));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -238,7 +278,7 @@ void wxCondition::Broadcast()
|
|||||||
|
|
||||||
wxCriticalSection::wxCriticalSection()
|
wxCriticalSection::wxCriticalSection()
|
||||||
{
|
{
|
||||||
wxASSERT_MSG( sizeof(CRITICAL_SECTION) == sizeof(m_buffer),
|
wxASSERT_MSG( sizeof(CRITICAL_SECTION) <= sizeof(m_buffer),
|
||||||
_T("must increase buffer size in wx/thread.h") );
|
_T("must increase buffer size in wx/thread.h") );
|
||||||
|
|
||||||
::InitializeCriticalSection((CRITICAL_SECTION *)m_buffer);
|
::InitializeCriticalSection((CRITICAL_SECTION *)m_buffer);
|
||||||
@@ -276,6 +316,24 @@ public:
|
|||||||
m_priority = WXTHREAD_DEFAULT_PRIORITY;
|
m_priority = WXTHREAD_DEFAULT_PRIORITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~wxThreadInternal()
|
||||||
|
{
|
||||||
|
Free();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Free()
|
||||||
|
{
|
||||||
|
if ( m_hThread )
|
||||||
|
{
|
||||||
|
if ( !::CloseHandle(m_hThread) )
|
||||||
|
{
|
||||||
|
wxLogLastError("CloseHandle(thread)");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_hThread = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// create a new (suspended) thread (for the given thread object)
|
// create a new (suspended) thread (for the given thread object)
|
||||||
bool Create(wxThread *thread);
|
bool Create(wxThread *thread);
|
||||||
|
|
||||||
@@ -289,7 +347,7 @@ public:
|
|||||||
wxThreadState GetState() const { return m_state; }
|
wxThreadState GetState() const { return m_state; }
|
||||||
|
|
||||||
// thread priority
|
// thread priority
|
||||||
void SetPriority(unsigned int priority) { m_priority = priority; }
|
void SetPriority(unsigned int priority);
|
||||||
unsigned int GetPriority() const { return m_priority; }
|
unsigned int GetPriority() const { return m_priority; }
|
||||||
|
|
||||||
// thread handle and id
|
// thread handle and id
|
||||||
@@ -309,41 +367,38 @@ private:
|
|||||||
DWORD wxThreadInternal::WinThreadStart(wxThread *thread)
|
DWORD wxThreadInternal::WinThreadStart(wxThread *thread)
|
||||||
{
|
{
|
||||||
// store the thread object in the TLS
|
// store the thread object in the TLS
|
||||||
if ( !::TlsSetValue(s_tlsThisThread, thread) )
|
if ( !::TlsSetValue(gs_tlsThisThread, thread) )
|
||||||
{
|
{
|
||||||
wxLogSysError(_("Can not start thread: error writing TLS."));
|
wxLogSysError(_("Can not start thread: error writing TLS."));
|
||||||
|
|
||||||
return (DWORD)-1;
|
return (DWORD)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD ret = (DWORD)thread->Entry();
|
DWORD rc = (DWORD)thread->Entry();
|
||||||
|
|
||||||
|
// enter m_critsect before changing the thread state
|
||||||
|
thread->m_critsect.Enter();
|
||||||
|
bool wasCancelled = thread->p_internal->GetState() == STATE_CANCELED;
|
||||||
thread->p_internal->SetState(STATE_EXITED);
|
thread->p_internal->SetState(STATE_EXITED);
|
||||||
|
thread->m_critsect.Leave();
|
||||||
|
|
||||||
thread->OnExit();
|
thread->OnExit();
|
||||||
|
|
||||||
|
// if the thread was cancelled (from Delete()), then it the handle is still
|
||||||
|
// needed there
|
||||||
|
if ( thread->IsDetached() && !wasCancelled )
|
||||||
|
{
|
||||||
|
// auto delete
|
||||||
delete thread;
|
delete thread;
|
||||||
|
}
|
||||||
|
//else: the joinable threads handle will be closed when Wait() is done
|
||||||
|
|
||||||
return ret;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxThreadInternal::Create(wxThread *thread)
|
void wxThreadInternal::SetPriority(unsigned int priority)
|
||||||
{
|
{
|
||||||
m_hThread = ::CreateThread
|
m_priority = priority;
|
||||||
(
|
|
||||||
NULL, // default security
|
|
||||||
0, // default stack size
|
|
||||||
(LPTHREAD_START_ROUTINE) // thread entry point
|
|
||||||
wxThreadInternal::WinThreadStart, //
|
|
||||||
(LPVOID)thread, // parameter
|
|
||||||
CREATE_SUSPENDED, // flags
|
|
||||||
&m_tid // [out] thread id
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( m_hThread == NULL )
|
|
||||||
{
|
|
||||||
wxLogSysError(_("Can't create thread"));
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// translate wxWindows priority to the Windows one
|
// translate wxWindows priority to the Windows one
|
||||||
int win_priority;
|
int win_priority;
|
||||||
@@ -363,10 +418,49 @@ bool wxThreadInternal::Create(wxThread *thread)
|
|||||||
win_priority = THREAD_PRIORITY_NORMAL;
|
win_priority = THREAD_PRIORITY_NORMAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ::SetThreadPriority(m_hThread, win_priority) == 0 )
|
if ( !::SetThreadPriority(m_hThread, win_priority) )
|
||||||
{
|
{
|
||||||
wxLogSysError(_("Can't set thread priority"));
|
wxLogSysError(_("Can't set thread priority"));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxThreadInternal::Create(wxThread *thread)
|
||||||
|
{
|
||||||
|
// for compilers which have it, we should use C RTL function for thread
|
||||||
|
// creation instead of Win32 API one because otherwise we will have memory
|
||||||
|
// leaks if the thread uses C RTL (and most threads do)
|
||||||
|
#ifdef __VISUALC__
|
||||||
|
typedef unsigned (__stdcall *RtlThreadStart)(void *);
|
||||||
|
|
||||||
|
m_hThread = (HANDLE)_beginthreadex(NULL, 0,
|
||||||
|
(RtlThreadStart)
|
||||||
|
wxThreadInternal::WinThreadStart,
|
||||||
|
thread, CREATE_SUSPENDED,
|
||||||
|
(unsigned int *)&m_tid);
|
||||||
|
#else // !VC++
|
||||||
|
m_hThread = ::CreateThread
|
||||||
|
(
|
||||||
|
NULL, // default security
|
||||||
|
0, // default stack size
|
||||||
|
(LPTHREAD_START_ROUTINE) // thread entry point
|
||||||
|
wxThreadInternal::WinThreadStart, //
|
||||||
|
(LPVOID)thread, // parameter
|
||||||
|
CREATE_SUSPENDED, // flags
|
||||||
|
&m_tid // [out] thread id
|
||||||
|
);
|
||||||
|
#endif // VC++/!VC++
|
||||||
|
|
||||||
|
if ( m_hThread == NULL )
|
||||||
|
{
|
||||||
|
wxLogSysError(_("Can't create thread"));
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_priority != WXTHREAD_DEFAULT_PRIORITY )
|
||||||
|
{
|
||||||
|
SetPriority(m_priority);
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -406,7 +500,7 @@ bool wxThreadInternal::Resume()
|
|||||||
|
|
||||||
wxThread *wxThread::This()
|
wxThread *wxThread::This()
|
||||||
{
|
{
|
||||||
wxThread *thread = (wxThread *)::TlsGetValue(s_tlsThisThread);
|
wxThread *thread = (wxThread *)::TlsGetValue(gs_tlsThisThread);
|
||||||
|
|
||||||
// be careful, 0 may be a valid return value as well
|
// be careful, 0 may be a valid return value as well
|
||||||
if ( !thread && (::GetLastError() != NO_ERROR) )
|
if ( !thread && (::GetLastError() != NO_ERROR) )
|
||||||
@@ -421,16 +515,13 @@ wxThread *wxThread::This()
|
|||||||
|
|
||||||
bool wxThread::IsMain()
|
bool wxThread::IsMain()
|
||||||
{
|
{
|
||||||
return ::GetCurrentThreadId() == s_idMainThread;
|
return ::GetCurrentThreadId() == gs_idMainThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Yield
|
|
||||||
#undef Yield
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void wxThread::Yield()
|
void wxThread::Yield()
|
||||||
{
|
{
|
||||||
// 0 argument to Sleep() is special
|
// 0 argument to Sleep() is special and means to just give away the rest of
|
||||||
|
// our timeslice
|
||||||
::Sleep(0);
|
::Sleep(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -439,11 +530,28 @@ void wxThread::Sleep(unsigned long milliseconds)
|
|||||||
::Sleep(milliseconds);
|
::Sleep(milliseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ctor and dtor
|
||||||
|
// -------------
|
||||||
|
|
||||||
|
wxThread::wxThread(wxThreadKind kind)
|
||||||
|
{
|
||||||
|
p_internal = new wxThreadInternal();
|
||||||
|
|
||||||
|
m_isDetached = kind == wxTHREAD_DETACHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxThread::~wxThread()
|
||||||
|
{
|
||||||
|
delete p_internal;
|
||||||
|
}
|
||||||
|
|
||||||
// create/start thread
|
// create/start thread
|
||||||
// -------------------
|
// -------------------
|
||||||
|
|
||||||
wxThreadError wxThread::Create()
|
wxThreadError wxThread::Create()
|
||||||
{
|
{
|
||||||
|
wxCriticalSectionLocker lock(m_critsect);
|
||||||
|
|
||||||
if ( !p_internal->Create(this) )
|
if ( !p_internal->Create(this) )
|
||||||
return wxTHREAD_NO_RESOURCE;
|
return wxTHREAD_NO_RESOURCE;
|
||||||
|
|
||||||
@@ -460,6 +568,7 @@ wxThreadError wxThread::Run()
|
|||||||
return wxTHREAD_RUNNING;
|
return wxTHREAD_RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// the thread has just been created and is still suspended - let it run
|
||||||
return Resume();
|
return Resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -483,7 +592,23 @@ wxThreadError wxThread::Resume()
|
|||||||
// stopping thread
|
// stopping thread
|
||||||
// ---------------
|
// ---------------
|
||||||
|
|
||||||
wxThread::ExitCode wxThread::Delete()
|
wxThread::ExitCode wxThread::Wait()
|
||||||
|
{
|
||||||
|
// although under Windows we can wait for any thread, it's an error to
|
||||||
|
// wait for a detached one in wxWin API
|
||||||
|
wxCHECK_MSG( !IsDetached(), (ExitCode)-1,
|
||||||
|
_T("can't wait for detached thread") );
|
||||||
|
|
||||||
|
ExitCode rc = (ExitCode)-1;
|
||||||
|
|
||||||
|
(void)Delete(&rc);
|
||||||
|
|
||||||
|
p_internal->Free();
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxThreadError wxThread::Delete(ExitCode *pRc)
|
||||||
{
|
{
|
||||||
ExitCode rc = 0;
|
ExitCode rc = 0;
|
||||||
|
|
||||||
@@ -491,24 +616,28 @@ wxThread::ExitCode wxThread::Delete()
|
|||||||
if ( IsPaused() )
|
if ( IsPaused() )
|
||||||
Resume();
|
Resume();
|
||||||
|
|
||||||
|
HANDLE hThread = p_internal->GetHandle();
|
||||||
|
|
||||||
if ( IsRunning() )
|
if ( IsRunning() )
|
||||||
{
|
{
|
||||||
if ( IsMain() )
|
if ( IsMain() )
|
||||||
{
|
{
|
||||||
// set flag for wxIsWaitingForThread()
|
// set flag for wxIsWaitingForThread()
|
||||||
s_waitingForThread = TRUE;
|
gs_waitingForThread = TRUE;
|
||||||
|
|
||||||
|
#if wxUSE_GUI
|
||||||
wxBeginBusyCursor();
|
wxBeginBusyCursor();
|
||||||
|
#endif // wxUSE_GUI
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE hThread;
|
// ask the thread to terminate
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker lock(m_critsect);
|
wxCriticalSectionLocker lock(m_critsect);
|
||||||
|
|
||||||
p_internal->Cancel();
|
p_internal->Cancel();
|
||||||
hThread = p_internal->GetHandle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if wxUSE_GUI
|
||||||
// we can't just wait for the thread to terminate because it might be
|
// we can't just wait for the thread to terminate because it might be
|
||||||
// calling some GUI functions and so it will never terminate before we
|
// calling some GUI functions and so it will never terminate before we
|
||||||
// process the Windows messages that result from these functions
|
// process the Windows messages that result from these functions
|
||||||
@@ -530,7 +659,7 @@ wxThread::ExitCode wxThread::Delete()
|
|||||||
// error
|
// error
|
||||||
wxLogSysError(_("Can not wait for thread termination"));
|
wxLogSysError(_("Can not wait for thread termination"));
|
||||||
Kill();
|
Kill();
|
||||||
return (ExitCode)-1;
|
return wxTHREAD_KILLED;
|
||||||
|
|
||||||
case WAIT_OBJECT_0:
|
case WAIT_OBJECT_0:
|
||||||
// thread we're waiting for terminated
|
// thread we're waiting for terminated
|
||||||
@@ -543,14 +672,14 @@ wxThread::ExitCode wxThread::Delete()
|
|||||||
// WM_QUIT received: kill the thread
|
// WM_QUIT received: kill the thread
|
||||||
Kill();
|
Kill();
|
||||||
|
|
||||||
return (ExitCode)-1;
|
return wxTHREAD_KILLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( IsMain() )
|
if ( IsMain() )
|
||||||
{
|
{
|
||||||
// give the thread we're waiting for chance to exit
|
// give the thread we're waiting for chance to exit
|
||||||
// from the GUI call it might have been in
|
// from the GUI call it might have been in
|
||||||
if ( (s_nWaitingForGui > 0) && wxGuiOwnedByMainThread() )
|
if ( (gs_nWaitingForGui > 0) && wxGuiOwnedByMainThread() )
|
||||||
{
|
{
|
||||||
wxMutexGuiLeave();
|
wxMutexGuiLeave();
|
||||||
}
|
}
|
||||||
@@ -562,12 +691,25 @@ wxThread::ExitCode wxThread::Delete()
|
|||||||
wxFAIL_MSG(wxT("unexpected result of MsgWaitForMultipleObject"));
|
wxFAIL_MSG(wxT("unexpected result of MsgWaitForMultipleObject"));
|
||||||
}
|
}
|
||||||
} while ( result != WAIT_OBJECT_0 );
|
} while ( result != WAIT_OBJECT_0 );
|
||||||
|
#else // !wxUSE_GUI
|
||||||
|
// simply wait for the thread to terminate
|
||||||
|
//
|
||||||
|
// OTOH, even console apps create windows (in wxExecute, for WinSock
|
||||||
|
// &c), so may be use MsgWaitForMultipleObject() too here?
|
||||||
|
if ( WaitForSingleObject(hThread, INFINITE) != WAIT_OBJECT_0 )
|
||||||
|
{
|
||||||
|
wxFAIL_MSG(wxT("unexpected result of WaitForSingleObject"));
|
||||||
|
}
|
||||||
|
#endif // wxUSE_GUI/!wxUSE_GUI
|
||||||
|
|
||||||
if ( IsMain() )
|
if ( IsMain() )
|
||||||
{
|
{
|
||||||
s_waitingForThread = FALSE;
|
gs_waitingForThread = FALSE;
|
||||||
|
|
||||||
|
#if wxUSE_GUI
|
||||||
wxEndBusyCursor();
|
wxEndBusyCursor();
|
||||||
|
#endif // wxUSE_GUI
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !::GetExitCodeThread(hThread, (LPDWORD)&rc) )
|
if ( !::GetExitCodeThread(hThread, (LPDWORD)&rc) )
|
||||||
@@ -577,13 +719,22 @@ wxThread::ExitCode wxThread::Delete()
|
|||||||
rc = (ExitCode)-1;
|
rc = (ExitCode)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxASSERT_MSG( (LPVOID)rc != (LPVOID)STILL_ACTIVE,
|
if ( IsDetached() )
|
||||||
wxT("thread must be already terminated.") );
|
{
|
||||||
|
// if the thread exits normally, this is done in WinThreadStart, but in
|
||||||
::CloseHandle(hThread);
|
// this case it would have been too early because
|
||||||
|
// MsgWaitForMultipleObject() would fail if the therad handle was
|
||||||
|
// closed while we were waiting on it, so we must do it here
|
||||||
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
wxASSERT_MSG( (DWORD)rc != STILL_ACTIVE,
|
||||||
|
wxT("thread must be already terminated.") );
|
||||||
|
|
||||||
|
if ( pRc )
|
||||||
|
*pRc = rc;
|
||||||
|
|
||||||
|
return rc == (ExitCode)-1 ? wxTHREAD_MISC_ERROR : wxTHREAD_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxThreadError wxThread::Kill()
|
wxThreadError wxThread::Kill()
|
||||||
@@ -598,20 +749,37 @@ wxThreadError wxThread::Kill()
|
|||||||
return wxTHREAD_MISC_ERROR;
|
return wxTHREAD_MISC_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p_internal->Free();
|
||||||
|
|
||||||
|
if ( IsDetached() )
|
||||||
|
{
|
||||||
delete this;
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
return wxTHREAD_NO_ERROR;
|
return wxTHREAD_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxThread::Exit(void *status)
|
void wxThread::Exit(ExitCode status)
|
||||||
{
|
{
|
||||||
delete this;
|
p_internal->Free();
|
||||||
|
|
||||||
|
if ( IsDetached() )
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __VISUALC__
|
||||||
|
_endthreadex((unsigned)status);
|
||||||
|
#else // !VC++
|
||||||
::ExitThread((DWORD)status);
|
::ExitThread((DWORD)status);
|
||||||
|
#endif // VC++/!VC++
|
||||||
|
|
||||||
wxFAIL_MSG(wxT("Couldn't return from ExitThread()!"));
|
wxFAIL_MSG(wxT("Couldn't return from ExitThread()!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// priority setting
|
||||||
|
// ----------------
|
||||||
|
|
||||||
void wxThread::SetPriority(unsigned int prio)
|
void wxThread::SetPriority(unsigned int prio)
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker lock(m_critsect);
|
wxCriticalSectionLocker lock(m_critsect);
|
||||||
@@ -621,28 +789,28 @@ void wxThread::SetPriority(unsigned int prio)
|
|||||||
|
|
||||||
unsigned int wxThread::GetPriority() const
|
unsigned int wxThread::GetPriority() const
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect);
|
wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect); // const_cast
|
||||||
|
|
||||||
return p_internal->GetPriority();
|
return p_internal->GetPriority();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long wxThread::GetID() const
|
unsigned long wxThread::GetId() const
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect);
|
wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect); // const_cast
|
||||||
|
|
||||||
return (unsigned long)p_internal->GetId();
|
return (unsigned long)p_internal->GetId();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxThread::IsRunning() const
|
bool wxThread::IsRunning() const
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect);
|
wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect); // const_cast
|
||||||
|
|
||||||
return p_internal->GetState() == STATE_RUNNING;
|
return p_internal->GetState() == STATE_RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxThread::IsAlive() const
|
bool wxThread::IsAlive() const
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect);
|
wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect); // const_cast
|
||||||
|
|
||||||
return (p_internal->GetState() == STATE_RUNNING) ||
|
return (p_internal->GetState() == STATE_RUNNING) ||
|
||||||
(p_internal->GetState() == STATE_PAUSED);
|
(p_internal->GetState() == STATE_PAUSED);
|
||||||
@@ -650,28 +818,18 @@ bool wxThread::IsAlive() const
|
|||||||
|
|
||||||
bool wxThread::IsPaused() const
|
bool wxThread::IsPaused() const
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect);
|
wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect); // const_cast
|
||||||
|
|
||||||
return (p_internal->GetState() == STATE_PAUSED);
|
return p_internal->GetState() == STATE_PAUSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxThread::TestDestroy()
|
bool wxThread::TestDestroy()
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect);
|
wxCriticalSectionLocker lock((wxCriticalSection &)m_critsect); // const_cast
|
||||||
|
|
||||||
return p_internal->GetState() == STATE_CANCELED;
|
return p_internal->GetState() == STATE_CANCELED;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxThread::wxThread()
|
|
||||||
{
|
|
||||||
p_internal = new wxThreadInternal();
|
|
||||||
}
|
|
||||||
|
|
||||||
wxThread::~wxThread()
|
|
||||||
{
|
|
||||||
delete p_internal;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Automatic initialization for thread module
|
// Automatic initialization for thread module
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -691,8 +849,8 @@ IMPLEMENT_DYNAMIC_CLASS(wxThreadModule, wxModule)
|
|||||||
bool wxThreadModule::OnInit()
|
bool wxThreadModule::OnInit()
|
||||||
{
|
{
|
||||||
// allocate TLS index for storing the pointer to the current thread
|
// allocate TLS index for storing the pointer to the current thread
|
||||||
s_tlsThisThread = ::TlsAlloc();
|
gs_tlsThisThread = ::TlsAlloc();
|
||||||
if ( s_tlsThisThread == 0xFFFFFFFF )
|
if ( gs_tlsThisThread == 0xFFFFFFFF )
|
||||||
{
|
{
|
||||||
// in normal circumstances it will only happen if all other
|
// in normal circumstances it will only happen if all other
|
||||||
// TLS_MINIMUM_AVAILABLE (>= 64) indices are already taken - in other
|
// TLS_MINIMUM_AVAILABLE (>= 64) indices are already taken - in other
|
||||||
@@ -706,10 +864,10 @@ bool wxThreadModule::OnInit()
|
|||||||
|
|
||||||
// main thread doesn't have associated wxThread object, so store 0 in the
|
// main thread doesn't have associated wxThread object, so store 0 in the
|
||||||
// TLS instead
|
// TLS instead
|
||||||
if ( !::TlsSetValue(s_tlsThisThread, (LPVOID)0) )
|
if ( !::TlsSetValue(gs_tlsThisThread, (LPVOID)0) )
|
||||||
{
|
{
|
||||||
::TlsFree(s_tlsThisThread);
|
::TlsFree(gs_tlsThisThread);
|
||||||
s_tlsThisThread = 0xFFFFFFFF;
|
gs_tlsThisThread = 0xFFFFFFFF;
|
||||||
|
|
||||||
wxLogSysError(_("Thread module initialization failed: "
|
wxLogSysError(_("Thread module initialization failed: "
|
||||||
"can not store value in thread local storage"));
|
"can not store value in thread local storage"));
|
||||||
@@ -717,36 +875,37 @@ bool wxThreadModule::OnInit()
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
s_critsectWaitingForGui = new wxCriticalSection();
|
gs_critsectWaitingForGui = new wxCriticalSection();
|
||||||
|
|
||||||
s_critsectGui = new wxCriticalSection();
|
gs_critsectGui = new wxCriticalSection();
|
||||||
s_critsectGui->Enter();
|
gs_critsectGui->Enter();
|
||||||
|
|
||||||
// no error return for GetCurrentThreadId()
|
// no error return for GetCurrentThreadId()
|
||||||
s_idMainThread = ::GetCurrentThreadId();
|
gs_idMainThread = ::GetCurrentThreadId();
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxThreadModule::OnExit()
|
void wxThreadModule::OnExit()
|
||||||
{
|
{
|
||||||
if ( !::TlsFree(s_tlsThisThread) )
|
if ( !::TlsFree(gs_tlsThisThread) )
|
||||||
{
|
{
|
||||||
wxLogLastError("TlsFree failed.");
|
wxLogLastError("TlsFree failed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( s_critsectGui )
|
if ( gs_critsectGui )
|
||||||
{
|
{
|
||||||
s_critsectGui->Leave();
|
gs_critsectGui->Leave();
|
||||||
delete s_critsectGui;
|
delete gs_critsectGui;
|
||||||
s_critsectGui = NULL;
|
gs_critsectGui = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxDELETE(s_critsectWaitingForGui);
|
delete gs_critsectWaitingForGui;
|
||||||
|
gs_critsectWaitingForGui = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// under Windows, these functions are implemented usign a critical section and
|
// under Windows, these functions are implemented using a critical section and
|
||||||
// not a mutex, so the names are a bit confusing
|
// not a mutex, so the names are a bit confusing
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -760,38 +919,38 @@ void WXDLLEXPORT wxMutexGuiEnter()
|
|||||||
|
|
||||||
// set the flag telling to the main thread that we want to do some GUI
|
// set the flag telling to the main thread that we want to do some GUI
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker enter(*s_critsectWaitingForGui);
|
wxCriticalSectionLocker enter(*gs_critsectWaitingForGui);
|
||||||
|
|
||||||
s_nWaitingForGui++;
|
gs_nWaitingForGui++;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxWakeUpMainThread();
|
wxWakeUpMainThread();
|
||||||
|
|
||||||
// now we may block here because the main thread will soon let us in
|
// now we may block here because the main thread will soon let us in
|
||||||
// (during the next iteration of OnIdle())
|
// (during the next iteration of OnIdle())
|
||||||
s_critsectGui->Enter();
|
gs_critsectGui->Enter();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WXDLLEXPORT wxMutexGuiLeave()
|
void WXDLLEXPORT wxMutexGuiLeave()
|
||||||
{
|
{
|
||||||
wxCriticalSectionLocker enter(*s_critsectWaitingForGui);
|
wxCriticalSectionLocker enter(*gs_critsectWaitingForGui);
|
||||||
|
|
||||||
if ( wxThread::IsMain() )
|
if ( wxThread::IsMain() )
|
||||||
{
|
{
|
||||||
s_bGuiOwnedByMainThread = FALSE;
|
gs_bGuiOwnedByMainThread = FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// decrement the number of waiters now
|
// decrement the number of waiters now
|
||||||
wxASSERT_MSG( s_nWaitingForGui > 0,
|
wxASSERT_MSG( gs_nWaitingForGui > 0,
|
||||||
wxT("calling wxMutexGuiLeave() without entering it first?") );
|
wxT("calling wxMutexGuiLeave() without entering it first?") );
|
||||||
|
|
||||||
s_nWaitingForGui--;
|
gs_nWaitingForGui--;
|
||||||
|
|
||||||
wxWakeUpMainThread();
|
wxWakeUpMainThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
s_critsectGui->Leave();
|
gs_critsectGui->Leave();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WXDLLEXPORT wxMutexGuiLeaveOrEnter()
|
void WXDLLEXPORT wxMutexGuiLeaveOrEnter()
|
||||||
@@ -799,17 +958,17 @@ void WXDLLEXPORT wxMutexGuiLeaveOrEnter()
|
|||||||
wxASSERT_MSG( wxThread::IsMain(),
|
wxASSERT_MSG( wxThread::IsMain(),
|
||||||
wxT("only main thread may call wxMutexGuiLeaveOrEnter()!") );
|
wxT("only main thread may call wxMutexGuiLeaveOrEnter()!") );
|
||||||
|
|
||||||
wxCriticalSectionLocker enter(*s_critsectWaitingForGui);
|
wxCriticalSectionLocker enter(*gs_critsectWaitingForGui);
|
||||||
|
|
||||||
if ( s_nWaitingForGui == 0 )
|
if ( gs_nWaitingForGui == 0 )
|
||||||
{
|
{
|
||||||
// no threads are waiting for GUI - so we may acquire the lock without
|
// no threads are waiting for GUI - so we may acquire the lock without
|
||||||
// any danger (but only if we don't already have it)
|
// any danger (but only if we don't already have it)
|
||||||
if ( !wxGuiOwnedByMainThread() )
|
if ( !wxGuiOwnedByMainThread() )
|
||||||
{
|
{
|
||||||
s_critsectGui->Enter();
|
gs_critsectGui->Enter();
|
||||||
|
|
||||||
s_bGuiOwnedByMainThread = TRUE;
|
gs_bGuiOwnedByMainThread = TRUE;
|
||||||
}
|
}
|
||||||
//else: already have it, nothing to do
|
//else: already have it, nothing to do
|
||||||
}
|
}
|
||||||
@@ -826,14 +985,14 @@ void WXDLLEXPORT wxMutexGuiLeaveOrEnter()
|
|||||||
|
|
||||||
bool WXDLLEXPORT wxGuiOwnedByMainThread()
|
bool WXDLLEXPORT wxGuiOwnedByMainThread()
|
||||||
{
|
{
|
||||||
return s_bGuiOwnedByMainThread;
|
return gs_bGuiOwnedByMainThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
// wake up the main thread if it's in ::GetMessage()
|
// wake up the main thread if it's in ::GetMessage()
|
||||||
void WXDLLEXPORT wxWakeUpMainThread()
|
void WXDLLEXPORT wxWakeUpMainThread()
|
||||||
{
|
{
|
||||||
// sending any message would do - hopefully WM_NULL is harmless enough
|
// sending any message would do - hopefully WM_NULL is harmless enough
|
||||||
if ( !::PostThreadMessage(s_idMainThread, WM_NULL, 0, 0) )
|
if ( !::PostThreadMessage(gs_idMainThread, WM_NULL, 0, 0) )
|
||||||
{
|
{
|
||||||
// should never happen
|
// should never happen
|
||||||
wxLogLastError("PostThreadMessage(WM_NULL)");
|
wxLogLastError("PostThreadMessage(WM_NULL)");
|
||||||
@@ -842,7 +1001,7 @@ void WXDLLEXPORT wxWakeUpMainThread()
|
|||||||
|
|
||||||
bool WXDLLEXPORT wxIsWaitingForThread()
|
bool WXDLLEXPORT wxIsWaitingForThread()
|
||||||
{
|
{
|
||||||
return s_waitingForThread;
|
return gs_waitingForThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // wxUSE_THREADS
|
#endif // wxUSE_THREADS
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// Name: utils.cpp
|
// Name: mse/utils.cpp
|
||||||
// Purpose: Various utilities
|
// Purpose: Various utilities
|
||||||
// Author: Julian Smart
|
// Author: Julian Smart
|
||||||
// Modified by:
|
// Modified by:
|
||||||
@@ -9,6 +9,14 @@
|
|||||||
// Licence: wxWindows license
|
// Licence: wxWindows license
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// declarations
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// headers
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifdef __GNUG__
|
#ifdef __GNUG__
|
||||||
// #pragma implementation "utils.h" // Note: this is done in utilscmn.cpp now.
|
// #pragma implementation "utils.h" // Note: this is done in utilscmn.cpp now.
|
||||||
#endif
|
#endif
|
||||||
@@ -21,18 +29,16 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
#ifndef WX_PRECOMP
|
||||||
#include "wx/setup.h"
|
|
||||||
#include "wx/utils.h"
|
#include "wx/utils.h"
|
||||||
#include "wx/app.h"
|
#include "wx/app.h"
|
||||||
#include "wx/cursor.h"
|
#include "wx/cursor.h"
|
||||||
#endif //WX_PRECOMP
|
#endif //WX_PRECOMP
|
||||||
|
|
||||||
#include "wx/msw/private.h"
|
#include "wx/msw/private.h" // includes <windows.h>
|
||||||
|
|
||||||
#include "wx/timer.h"
|
#include "wx/timer.h"
|
||||||
#include "wx/intl.h"
|
#include "wx/intl.h"
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#if !defined(__GNUWIN32__) && !defined(__WXWINE__) && !defined(__SALFORDC__)
|
#if !defined(__GNUWIN32__) && !defined(__WXWINE__) && !defined(__SALFORDC__)
|
||||||
@@ -118,23 +124,43 @@
|
|||||||
// __VISUALC__
|
// __VISUALC__
|
||||||
/// END for console support
|
/// END for console support
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// constants
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// In the WIN.INI file
|
// In the WIN.INI file
|
||||||
static const wxChar WX_SECTION[] = wxT("wxWindows");
|
static const wxChar WX_SECTION[] = wxT("wxWindows");
|
||||||
static const wxChar eHOSTNAME[] = wxT("HostName");
|
|
||||||
static const wxChar eUSERID[] = wxT("UserId");
|
|
||||||
static const wxChar eUSERNAME[] = wxT("UserName");
|
static const wxChar eUSERNAME[] = wxT("UserName");
|
||||||
|
|
||||||
// For the following functions we SHOULD fill in support
|
// these are only used under Win16
|
||||||
// for Windows-NT (which I don't know) as I assume it begin
|
#ifndef __WIN32__
|
||||||
// a POSIX Unix (so claims MS) that it has some special
|
static const wxChar eHOSTNAME[] = wxT("HostName");
|
||||||
// functions beyond those provided by WinSock
|
static const wxChar eUSERID[] = wxT("UserId");
|
||||||
|
#endif // !Win32
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// implementation
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// get host name and related
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Get full hostname (eg. DoDo.BSn-Germany.crg.de)
|
// Get full hostname (eg. DoDo.BSn-Germany.crg.de)
|
||||||
bool wxGetHostName(wxChar *buf, int maxSize)
|
bool wxGetHostName(wxChar *buf, int maxSize)
|
||||||
{
|
{
|
||||||
#if defined(__WIN32__) && !defined(__TWIN32__)
|
#if defined(__WIN32__) && !defined(__TWIN32__)
|
||||||
|
// TODO should use GetComputerNameEx() when available
|
||||||
|
|
||||||
DWORD nSize = maxSize;
|
DWORD nSize = maxSize;
|
||||||
return (::GetComputerName(buf, &nSize) != 0);
|
if ( !::GetComputerName(buf, &nSize) )
|
||||||
|
{
|
||||||
|
wxLogLastError("GetComputerName");
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
#else
|
#else
|
||||||
wxChar *sysname;
|
wxChar *sysname;
|
||||||
const wxChar *default_host = wxT("noname");
|
const wxChar *default_host = wxT("noname");
|
||||||
@@ -148,6 +174,11 @@ bool wxGetHostName(wxChar *buf, int maxSize)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxGetFullHostName(wxChar *buf, int maxSize)
|
||||||
|
{
|
||||||
|
return wxGetHostName(buf, maxSize);
|
||||||
|
}
|
||||||
|
|
||||||
// Get user ID e.g. jacs
|
// Get user ID e.g. jacs
|
||||||
bool wxGetUserId(wxChar *buf, int maxSize)
|
bool wxGetUserId(wxChar *buf, int maxSize)
|
||||||
{
|
{
|
||||||
@@ -286,30 +317,150 @@ error:
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const wxChar* wxGetHomeDir(wxString *pstr)
|
||||||
|
{
|
||||||
|
wxString& strDir = *pstr;
|
||||||
|
|
||||||
|
#if defined(__UNIX__) && !defined(__TWIN32__)
|
||||||
|
const wxChar *szHome = wxGetenv("HOME");
|
||||||
|
if ( szHome == NULL ) {
|
||||||
|
// we're homeless...
|
||||||
|
wxLogWarning(_("can't find user's HOME, using current directory."));
|
||||||
|
strDir = wxT(".");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strDir = szHome;
|
||||||
|
|
||||||
|
// add a trailing slash if needed
|
||||||
|
if ( strDir.Last() != wxT('/') )
|
||||||
|
strDir << wxT('/');
|
||||||
|
#else // Windows
|
||||||
|
#ifdef __WIN32__
|
||||||
|
const wxChar *szHome = wxGetenv(wxT("HOMEDRIVE"));
|
||||||
|
if ( szHome != NULL )
|
||||||
|
strDir << szHome;
|
||||||
|
szHome = wxGetenv(wxT("HOMEPATH"));
|
||||||
|
if ( szHome != NULL ) {
|
||||||
|
strDir << szHome;
|
||||||
|
|
||||||
|
// the idea is that under NT these variables have default values
|
||||||
|
// of "%systemdrive%:" and "\\". As we don't want to create our
|
||||||
|
// config files in the root directory of the system drive, we will
|
||||||
|
// create it in our program's dir. However, if the user took care
|
||||||
|
// to set HOMEPATH to something other than "\\", we suppose that he
|
||||||
|
// knows what he is doing and use the supplied value.
|
||||||
|
if ( wxStrcmp(szHome, wxT("\\")) != 0 )
|
||||||
|
return strDir.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // Win16
|
||||||
|
// Win16 has no idea about home, so use the working directory instead
|
||||||
|
#endif // WIN16/32
|
||||||
|
|
||||||
|
// 260 was taken from windef.h
|
||||||
|
#ifndef MAX_PATH
|
||||||
|
#define MAX_PATH 260
|
||||||
|
#endif
|
||||||
|
|
||||||
|
wxString strPath;
|
||||||
|
::GetModuleFileName(::GetModuleHandle(NULL),
|
||||||
|
strPath.GetWriteBuf(MAX_PATH), MAX_PATH);
|
||||||
|
strPath.UngetWriteBuf();
|
||||||
|
|
||||||
|
// extract the dir name
|
||||||
|
wxSplitPath(strPath, &strDir, NULL, NULL);
|
||||||
|
|
||||||
|
#endif // UNIX/Win
|
||||||
|
|
||||||
|
return strDir.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
wxChar *wxGetUserHome(const wxString& user)
|
||||||
|
{
|
||||||
|
// VZ: the old code here never worked for user != "" anyhow! Moreover, it
|
||||||
|
// returned sometimes a malloc()'d pointer, sometimes a pointer to a
|
||||||
|
// static buffer and sometimes I don't even know what.
|
||||||
|
static wxString s_home;
|
||||||
|
|
||||||
|
return (wxChar *)wxGetHomeDir(&s_home);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxDirExists(const wxString& dir)
|
||||||
|
{
|
||||||
|
#if defined(__WIN32__)
|
||||||
|
WIN32_FIND_DATA fileInfo;
|
||||||
|
#else // Win16
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
struct ffblk fileInfo;
|
||||||
|
#else
|
||||||
|
struct find_t fileInfo;
|
||||||
|
#endif
|
||||||
|
#endif // Win32/16
|
||||||
|
|
||||||
|
#if defined(__WIN32__)
|
||||||
|
HANDLE h = ::FindFirstFile(dir, &fileInfo);
|
||||||
|
|
||||||
|
if ( h == INVALID_HANDLE_VALUE )
|
||||||
|
{
|
||||||
|
wxLogLastError("FindFirstFile");
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
::FindClose(h);
|
||||||
|
|
||||||
|
return (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||||
|
#else // Win16
|
||||||
|
// In Borland findfirst has a different argument
|
||||||
|
// ordering from _dos_findfirst. But _dos_findfirst
|
||||||
|
// _should_ be ok in both MS and Borland... why not?
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
return (findfirst(dir, &fileInfo, _A_SUBDIR) == 0 &&
|
||||||
|
(fileInfo.ff_attrib & _A_SUBDIR) != 0);
|
||||||
|
#else
|
||||||
|
return (_dos_findfirst(dir, _A_SUBDIR, &fileInfo) == 0) &&
|
||||||
|
((fileInfo.attrib & _A_SUBDIR) != 0);
|
||||||
|
#endif
|
||||||
|
#endif // Win32/16
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// process management
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
int wxKill(long pid, int sig)
|
int wxKill(long pid, int sig)
|
||||||
{
|
{
|
||||||
|
// TODO use SendMessage(WM_QUIT) and TerminateProcess() if needed
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Execute a program in an Interactive Shell
|
// Execute a program in an Interactive Shell
|
||||||
//
|
bool wxShell(const wxString& command)
|
||||||
bool
|
|
||||||
wxShell(const wxString& command)
|
|
||||||
{
|
{
|
||||||
wxChar *shell;
|
wxChar *shell = wxGetenv(wxT("COMSPEC"));
|
||||||
if ((shell = wxGetenv(wxT("COMSPEC"))) == NULL)
|
if ( !shell )
|
||||||
shell = wxT("\\COMMAND.COM");
|
shell = wxT("\\COMMAND.COM");
|
||||||
|
|
||||||
wxChar tmp[255];
|
wxString cmd;
|
||||||
if (command != wxT(""))
|
if ( !command )
|
||||||
wxSprintf(tmp, wxT("%s /c %s"), shell, WXSTRINGCAST command);
|
{
|
||||||
|
// just the shell
|
||||||
|
cmd = shell;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
wxStrcpy(tmp, shell);
|
{
|
||||||
|
// pass the command to execute to the command processor
|
||||||
|
cmd.Printf(wxT("%s /c %s"), shell, command.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
return (wxExecute((wxChar *)tmp, FALSE) != 0);
|
return wxExecute(cmd, FALSE) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// misc
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
|
// Get free memory in bytes, or -1 if cannot determine amount (e.g. on UNIX)
|
||||||
long wxGetFreeMemory()
|
long wxGetFreeMemory()
|
||||||
{
|
{
|
||||||
@@ -323,111 +474,10 @@ long wxGetFreeMemory()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sleep for nSecs seconds. Attempt a Windows implementation using timers.
|
|
||||||
static bool inTimer = FALSE;
|
|
||||||
class wxSleepTimer: public wxTimer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
inline void Notify()
|
|
||||||
{
|
|
||||||
inTimer = FALSE;
|
|
||||||
Stop();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static wxTimer *wxTheSleepTimer = NULL;
|
|
||||||
|
|
||||||
void wxUsleep(unsigned long milliseconds)
|
|
||||||
{
|
|
||||||
#ifdef __WIN32__
|
|
||||||
::Sleep(milliseconds);
|
|
||||||
#else
|
|
||||||
if (inTimer)
|
|
||||||
return;
|
|
||||||
|
|
||||||
wxTheSleepTimer = new wxSleepTimer;
|
|
||||||
inTimer = TRUE;
|
|
||||||
wxTheSleepTimer->Start(milliseconds);
|
|
||||||
while (inTimer)
|
|
||||||
{
|
|
||||||
if (wxTheApp->Pending())
|
|
||||||
wxTheApp->Dispatch();
|
|
||||||
}
|
|
||||||
delete wxTheSleepTimer;
|
|
||||||
wxTheSleepTimer = NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void wxSleep(int nSecs)
|
|
||||||
{
|
|
||||||
#if 0 // WIN32 hangs app
|
|
||||||
Sleep( 1000*nSecs );
|
|
||||||
#else
|
|
||||||
if (inTimer)
|
|
||||||
return;
|
|
||||||
|
|
||||||
wxTheSleepTimer = new wxSleepTimer;
|
|
||||||
inTimer = TRUE;
|
|
||||||
wxTheSleepTimer->Start(nSecs*1000);
|
|
||||||
while (inTimer)
|
|
||||||
{
|
|
||||||
if (wxTheApp->Pending())
|
|
||||||
wxTheApp->Dispatch();
|
|
||||||
}
|
|
||||||
delete wxTheSleepTimer;
|
|
||||||
wxTheSleepTimer = NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Consume all events until no more left
|
|
||||||
void wxFlushEvents()
|
|
||||||
{
|
|
||||||
// wxYield();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output a debug mess., in a system dependent fashion.
|
|
||||||
void wxDebugMsg(const wxChar *fmt ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
static wxChar buffer[512];
|
|
||||||
|
|
||||||
if (!wxTheApp->GetWantDebugOutput())
|
|
||||||
return ;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
|
|
||||||
wvsprintf(buffer,fmt,ap) ;
|
|
||||||
OutputDebugString((LPCTSTR)buffer) ;
|
|
||||||
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Non-fatal error: pop up message box and (possibly) continue
|
|
||||||
void wxError(const wxString& msg, const wxString& title)
|
|
||||||
{
|
|
||||||
wxSprintf(wxBuffer, wxT("%s\nContinue?"), WXSTRINGCAST msg);
|
|
||||||
if (MessageBox(NULL, (LPCTSTR)wxBuffer, (LPCTSTR)WXSTRINGCAST title,
|
|
||||||
MB_ICONSTOP | MB_YESNO) == IDNO)
|
|
||||||
wxExit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fatal error: pop up message box and abort
|
|
||||||
void wxFatalError(const wxString& msg, const wxString& title)
|
|
||||||
{
|
|
||||||
wxSprintf(wxBuffer, wxT("%s: %s"), WXSTRINGCAST title, WXSTRINGCAST msg);
|
|
||||||
FatalAppExit(0, (LPCTSTR)wxBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Emit a beeeeeep
|
// Emit a beeeeeep
|
||||||
void wxBell()
|
void wxBell()
|
||||||
{
|
{
|
||||||
// Removed by RD because IHMO syncronous sound is a Bad Thing. MessageBeep
|
::MessageBeep((UINT)-1); // default sound
|
||||||
// will do a similar thing anyway if there is no sound card...
|
|
||||||
//#ifdef __WIN32__
|
|
||||||
// Beep(1000,1000) ; // 1kHz during 1 sec.
|
|
||||||
//#else
|
|
||||||
MessageBeep((UINT)-1) ;
|
|
||||||
//#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Chris Breeze 27/5/98: revised WIN32 code to
|
// Chris Breeze 27/5/98: revised WIN32 code to
|
||||||
@@ -477,6 +527,128 @@ int wxGetOsVersion(int *majorVsn, int *minorVsn)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// sleep functions
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if wxUSE_GUI
|
||||||
|
|
||||||
|
// Sleep for nSecs seconds. Attempt a Windows implementation using timers.
|
||||||
|
static bool gs_inTimer = FALSE;
|
||||||
|
|
||||||
|
class wxSleepTimer: public wxTimer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void Notify()
|
||||||
|
{
|
||||||
|
gs_inTimer = FALSE;
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static wxTimer *wxTheSleepTimer = NULL;
|
||||||
|
|
||||||
|
void wxUsleep(unsigned long milliseconds)
|
||||||
|
{
|
||||||
|
#ifdef __WIN32__
|
||||||
|
::Sleep(milliseconds);
|
||||||
|
#else
|
||||||
|
if (gs_inTimer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wxTheSleepTimer = new wxSleepTimer;
|
||||||
|
gs_inTimer = TRUE;
|
||||||
|
wxTheSleepTimer->Start(milliseconds);
|
||||||
|
while (gs_inTimer)
|
||||||
|
{
|
||||||
|
if (wxTheApp->Pending())
|
||||||
|
wxTheApp->Dispatch();
|
||||||
|
}
|
||||||
|
delete wxTheSleepTimer;
|
||||||
|
wxTheSleepTimer = NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxSleep(int nSecs)
|
||||||
|
{
|
||||||
|
if (gs_inTimer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wxTheSleepTimer = new wxSleepTimer;
|
||||||
|
gs_inTimer = TRUE;
|
||||||
|
wxTheSleepTimer->Start(nSecs*1000);
|
||||||
|
while (gs_inTimer)
|
||||||
|
{
|
||||||
|
if (wxTheApp->Pending())
|
||||||
|
wxTheApp->Dispatch();
|
||||||
|
}
|
||||||
|
delete wxTheSleepTimer;
|
||||||
|
wxTheSleepTimer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Consume all events until no more left
|
||||||
|
void wxFlushEvents()
|
||||||
|
{
|
||||||
|
// wxYield();
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(__WIN32__) // wxUSE_GUI
|
||||||
|
|
||||||
|
void wxUsleep(unsigned long milliseconds)
|
||||||
|
{
|
||||||
|
::Sleep(milliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxSleep(int nSecs)
|
||||||
|
{
|
||||||
|
wxUsleep(1000*nSecs);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_GUI/!wxUSE_GUI
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// deprecated (in favour of wxLog) log functions
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if wxUSE_GUI
|
||||||
|
|
||||||
|
// Output a debug mess., in a system dependent fashion.
|
||||||
|
void wxDebugMsg(const wxChar *fmt ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
static wxChar buffer[512];
|
||||||
|
|
||||||
|
if (!wxTheApp->GetWantDebugOutput())
|
||||||
|
return ;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
|
||||||
|
wvsprintf(buffer,fmt,ap) ;
|
||||||
|
OutputDebugString((LPCTSTR)buffer) ;
|
||||||
|
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-fatal error: pop up message box and (possibly) continue
|
||||||
|
void wxError(const wxString& msg, const wxString& title)
|
||||||
|
{
|
||||||
|
wxSprintf(wxBuffer, wxT("%s\nContinue?"), WXSTRINGCAST msg);
|
||||||
|
if (MessageBox(NULL, (LPCTSTR)wxBuffer, (LPCTSTR)WXSTRINGCAST title,
|
||||||
|
MB_ICONSTOP | MB_YESNO) == IDNO)
|
||||||
|
wxExit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fatal error: pop up message box and abort
|
||||||
|
void wxFatalError(const wxString& msg, const wxString& title)
|
||||||
|
{
|
||||||
|
wxSprintf(wxBuffer, wxT("%s: %s"), WXSTRINGCAST title, WXSTRINGCAST msg);
|
||||||
|
FatalAppExit(0, (LPCTSTR)wxBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// functions to work with .INI files
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Reading and writing resources (eg WIN.INI, .Xdefaults)
|
// Reading and writing resources (eg WIN.INI, .Xdefaults)
|
||||||
#if wxUSE_RESOURCES
|
#if wxUSE_RESOURCES
|
||||||
bool wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file)
|
bool wxWriteResource(const wxString& section, const wxString& entry, const wxString& value, const wxString& file)
|
||||||
@@ -495,22 +667,25 @@ bool wxWriteResource(const wxString& section, const wxString& entry, const wxStr
|
|||||||
|
|
||||||
bool wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file)
|
bool wxWriteResource(const wxString& section, const wxString& entry, float value, const wxString& file)
|
||||||
{
|
{
|
||||||
wxChar buf[50];
|
wxString buf;
|
||||||
wxSprintf(buf, wxT("%.4f"), value);
|
buf.Printf(wxT("%.4f"), value);
|
||||||
|
|
||||||
return wxWriteResource(section, entry, buf, file);
|
return wxWriteResource(section, entry, buf, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file)
|
bool wxWriteResource(const wxString& section, const wxString& entry, long value, const wxString& file)
|
||||||
{
|
{
|
||||||
wxChar buf[50];
|
wxString buf;
|
||||||
wxSprintf(buf, wxT("%ld"), value);
|
buf.Printf(wxT("%ld"), value);
|
||||||
|
|
||||||
return wxWriteResource(section, entry, buf, file);
|
return wxWriteResource(section, entry, buf, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file)
|
bool wxWriteResource(const wxString& section, const wxString& entry, int value, const wxString& file)
|
||||||
{
|
{
|
||||||
wxChar buf[50];
|
wxString buf;
|
||||||
wxSprintf(buf, wxT("%d"), value);
|
buf.Printf(wxT("%d"), value);
|
||||||
|
|
||||||
return wxWriteResource(section, entry, buf, file);
|
return wxWriteResource(section, entry, buf, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -534,7 +709,7 @@ bool wxGetResource(const wxString& section, const wxString& entry, wxChar **valu
|
|||||||
if (*value) delete[] (*value);
|
if (*value) delete[] (*value);
|
||||||
*value = copystring(wxBuffer);
|
*value = copystring(wxBuffer);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file)
|
bool wxGetResource(const wxString& section, const wxString& entry, float *value, const wxString& file)
|
||||||
{
|
{
|
||||||
@@ -615,142 +790,42 @@ bool wxIsBusy()
|
|||||||
return (gs_wxBusyCursorCount > 0);
|
return (gs_wxBusyCursorCount > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
|
||||||
const wxChar* wxGetHomeDir(wxString *pstr)
|
|
||||||
{
|
|
||||||
wxString& strDir = *pstr;
|
|
||||||
|
|
||||||
#if defined(__UNIX__) && !defined(__TWIN32__)
|
|
||||||
const wxChar *szHome = wxGetenv("HOME");
|
|
||||||
if ( szHome == NULL ) {
|
|
||||||
// we're homeless...
|
|
||||||
wxLogWarning(_("can't find user's HOME, using current directory."));
|
|
||||||
strDir = wxT(".");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
strDir = szHome;
|
|
||||||
|
|
||||||
// add a trailing slash if needed
|
|
||||||
if ( strDir.Last() != wxT('/') )
|
|
||||||
strDir << wxT('/');
|
|
||||||
#else // Windows
|
|
||||||
#ifdef __WIN32__
|
|
||||||
const wxChar *szHome = wxGetenv(wxT("HOMEDRIVE"));
|
|
||||||
if ( szHome != NULL )
|
|
||||||
strDir << szHome;
|
|
||||||
szHome = wxGetenv(wxT("HOMEPATH"));
|
|
||||||
if ( szHome != NULL ) {
|
|
||||||
strDir << szHome;
|
|
||||||
|
|
||||||
// the idea is that under NT these variables have default values
|
|
||||||
// of "%systemdrive%:" and "\\". As we don't want to create our
|
|
||||||
// config files in the root directory of the system drive, we will
|
|
||||||
// create it in our program's dir. However, if the user took care
|
|
||||||
// to set HOMEPATH to something other than "\\", we suppose that he
|
|
||||||
// knows what he is doing and use the supplied value.
|
|
||||||
if ( wxStrcmp(szHome, wxT("\\")) != 0 )
|
|
||||||
return strDir.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
#else // Win16
|
|
||||||
// Win16 has no idea about home, so use the working directory instead
|
|
||||||
#endif // WIN16/32
|
|
||||||
|
|
||||||
// 260 was taken from windef.h
|
|
||||||
#ifndef MAX_PATH
|
|
||||||
#define MAX_PATH 260
|
|
||||||
#endif
|
|
||||||
|
|
||||||
wxString strPath;
|
|
||||||
::GetModuleFileName(::GetModuleHandle(NULL),
|
|
||||||
strPath.GetWriteBuf(MAX_PATH), MAX_PATH);
|
|
||||||
strPath.UngetWriteBuf();
|
|
||||||
|
|
||||||
// extract the dir name
|
|
||||||
wxSplitPath(strPath, &strDir, NULL, NULL);
|
|
||||||
|
|
||||||
#endif // UNIX/Win
|
|
||||||
|
|
||||||
return strDir.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hack for MS-DOS
|
|
||||||
wxChar *wxGetUserHome (const wxString& user)
|
|
||||||
{
|
|
||||||
wxChar *home;
|
|
||||||
wxString user1(user);
|
|
||||||
|
|
||||||
if (user1 != wxT("")) {
|
|
||||||
wxChar tmp[64];
|
|
||||||
if (wxGetUserId(tmp, sizeof(tmp)/sizeof(char))) {
|
|
||||||
// Guests belong in the temp dir
|
|
||||||
if (wxStricmp(tmp, wxT("annonymous")) == 0) {
|
|
||||||
if ((home = wxGetenv(wxT("TMP"))) != NULL ||
|
|
||||||
(home = wxGetenv(wxT("TMPDIR"))) != NULL ||
|
|
||||||
(home = wxGetenv(wxT("TEMP"))) != NULL)
|
|
||||||
return *home ? home : (wxChar*)wxT("\\");
|
|
||||||
}
|
|
||||||
if (wxStricmp(tmp, WXSTRINGCAST user1) == 0)
|
|
||||||
user1 = wxT("");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (user1 == wxT(""))
|
|
||||||
if ((home = wxGetenv(wxT("HOME"))) != NULL)
|
|
||||||
{
|
|
||||||
wxStrcpy(wxBuffer, home);
|
|
||||||
Unix2DosFilename(wxBuffer);
|
|
||||||
return wxBuffer;
|
|
||||||
}
|
|
||||||
return NULL; // No home known!
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check whether this window wants to process messages, e.g. Stop button
|
// Check whether this window wants to process messages, e.g. Stop button
|
||||||
// in long calculations.
|
// in long calculations.
|
||||||
bool wxCheckForInterrupt(wxWindow *wnd)
|
bool wxCheckForInterrupt(wxWindow *wnd)
|
||||||
{
|
{
|
||||||
if(wnd){
|
wxCHECK( wnd, FALSE );
|
||||||
MSG msg;
|
|
||||||
HWND win= (HWND) wnd->GetHWND();
|
|
||||||
while(PeekMessage(&msg,win,0,0,PM_REMOVE)){
|
|
||||||
TranslateMessage(&msg);
|
|
||||||
DispatchMessage(&msg);
|
|
||||||
}
|
|
||||||
return TRUE;//*** temporary?
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
wxFAIL_MSG(wxT("wnd==NULL !!!"));
|
|
||||||
|
|
||||||
return FALSE;//*** temporary?
|
MSG msg;
|
||||||
|
while ( ::PeekMessage(&msg, GetHwndOf(wnd), 0, 0, PM_REMOVE) )
|
||||||
|
{
|
||||||
|
::TranslateMessage(&msg);
|
||||||
|
::DispatchMessage(&msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_GUI
|
||||||
|
|
||||||
// MSW only: get user-defined resource from the .res file.
|
// MSW only: get user-defined resource from the .res file.
|
||||||
// Returns NULL or newly-allocated memory, so use delete[] to clean up.
|
// Returns NULL or newly-allocated memory, so use delete[] to clean up.
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
|
||||||
wxChar *wxLoadUserResource(const wxString& resourceName, const wxString& resourceType)
|
wxChar *wxLoadUserResource(const wxString& resourceName, const wxString& resourceType)
|
||||||
{
|
{
|
||||||
wxChar *s = NULL;
|
HRSRC hResource = ::FindResource(wxGetInstance(), resourceName, resourceType);
|
||||||
#if !defined(__WIN32__) || defined(__TWIN32__)
|
if ( hResource == 0 )
|
||||||
HRSRC hResource = ::FindResource(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
|
|
||||||
#else
|
|
||||||
#ifdef UNICODE
|
|
||||||
HRSRC hResource = ::FindResourceW(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
|
|
||||||
#else
|
|
||||||
HRSRC hResource = ::FindResourceA(wxGetInstance(), WXSTRINGCAST resourceName, WXSTRINGCAST resourceType);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (hResource == 0)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
HGLOBAL hData = ::LoadResource(wxGetInstance(), hResource);
|
HGLOBAL hData = ::LoadResource(wxGetInstance(), hResource);
|
||||||
if (hData == 0)
|
if ( hData == 0 )
|
||||||
return NULL;
|
|
||||||
wxChar *theText = (wxChar *)LockResource(hData);
|
|
||||||
if (!theText)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
s = copystring(theText);
|
wxChar *theText = (wxChar *)::LockResource(hData);
|
||||||
|
if ( !theText )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
wxChar *s = copystring(theText);
|
||||||
|
|
||||||
// Obsolete in WIN32
|
// Obsolete in WIN32
|
||||||
#ifndef __WIN32__
|
#ifndef __WIN32__
|
||||||
@@ -758,85 +833,46 @@ wxChar *wxLoadUserResource(const wxString& resourceName, const wxString& resourc
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// No need??
|
// No need??
|
||||||
// GlobalFree(hData);
|
// GlobalFree(hData);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// get display info
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
void wxGetMousePosition( int* x, int* y )
|
void wxGetMousePosition( int* x, int* y )
|
||||||
{
|
{
|
||||||
POINT pt;
|
POINT pt;
|
||||||
GetCursorPos( & pt );
|
GetCursorPos( & pt );
|
||||||
*x = pt.x;
|
if ( x ) *x = pt.x;
|
||||||
*y = pt.y;
|
if ( y ) *y = pt.y;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return TRUE if we have a colour display
|
// Return TRUE if we have a colour display
|
||||||
bool wxColourDisplay()
|
bool wxColourDisplay()
|
||||||
{
|
{
|
||||||
HDC dc = ::GetDC((HWND) NULL);
|
ScreenHDC dc;
|
||||||
bool flag;
|
|
||||||
int noCols = GetDeviceCaps(dc, NUMCOLORS);
|
int noCols = GetDeviceCaps(dc, NUMCOLORS);
|
||||||
if ((noCols == -1) || (noCols > 2))
|
|
||||||
flag = TRUE;
|
return (noCols == -1) || (noCols > 2);
|
||||||
else
|
|
||||||
flag = FALSE;
|
|
||||||
ReleaseDC((HWND) NULL, dc);
|
|
||||||
return flag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns depth of screen
|
// Returns depth of screen
|
||||||
int wxDisplayDepth()
|
int wxDisplayDepth()
|
||||||
{
|
{
|
||||||
HDC dc = ::GetDC((HWND) NULL);
|
ScreenHDC dc;
|
||||||
int planes = GetDeviceCaps(dc, PLANES);
|
return GetDeviceCaps(dc, PLANES) * GetDeviceCaps(dc, BITSPIXEL);
|
||||||
int bitsPerPixel = GetDeviceCaps(dc, BITSPIXEL);
|
|
||||||
int depth = planes*bitsPerPixel;
|
|
||||||
ReleaseDC((HWND) NULL, dc);
|
|
||||||
return depth;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get size of display
|
// Get size of display
|
||||||
void wxDisplaySize(int *width, int *height)
|
void wxDisplaySize(int *width, int *height)
|
||||||
{
|
{
|
||||||
HDC dc = ::GetDC((HWND) NULL);
|
ScreenHDC dc;
|
||||||
*width = GetDeviceCaps(dc, HORZRES); *height = GetDeviceCaps(dc, VERTRES);
|
|
||||||
ReleaseDC((HWND) NULL, dc);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wxDirExists(const wxString& dir)
|
if ( width ) *width = GetDeviceCaps(dc, HORZRES);
|
||||||
{
|
if ( height ) *height = GetDeviceCaps(dc, VERTRES);
|
||||||
/* MATTHEW: [6] Always use same code for Win32, call FindClose */
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
WIN32_FIND_DATA fileInfo;
|
|
||||||
#else
|
|
||||||
#ifdef __BORLANDC__
|
|
||||||
struct ffblk fileInfo;
|
|
||||||
#else
|
|
||||||
struct find_t fileInfo;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__WIN32__)
|
|
||||||
HANDLE h = FindFirstFile((LPTSTR) WXSTRINGCAST dir,(LPWIN32_FIND_DATA)&fileInfo);
|
|
||||||
|
|
||||||
if (h==INVALID_HANDLE_VALUE)
|
|
||||||
return FALSE;
|
|
||||||
else {
|
|
||||||
FindClose(h);
|
|
||||||
return ((fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// In Borland findfirst has a different argument
|
|
||||||
// ordering from _dos_findfirst. But _dos_findfirst
|
|
||||||
// _should_ be ok in both MS and Borland... why not?
|
|
||||||
#ifdef __BORLANDC__
|
|
||||||
return ((findfirst(WXSTRINGCAST dir, &fileInfo, _A_SUBDIR) == 0 && (fileInfo.ff_attrib & _A_SUBDIR) != 0));
|
|
||||||
#else
|
|
||||||
return (((_dos_findfirst(WXSTRINGCAST dir, _A_SUBDIR, &fileInfo) == 0) && (fileInfo.attrib & _A_SUBDIR)) != 0);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// Name: utilsexec.cpp
|
// Name: msw/utilsexec.cpp
|
||||||
// Purpose: Various utilities
|
// Purpose: Various utilities
|
||||||
// Author: Julian Smart
|
// Author: Julian Smart
|
||||||
// Modified by:
|
// Modified by:
|
||||||
@@ -9,48 +9,51 @@
|
|||||||
// Licence: wxWindows license
|
// Licence: wxWindows license
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// declarations
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// headers
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifdef __GNUG__
|
#ifdef __GNUG__
|
||||||
#pragma implementation
|
#pragma implementation
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// For compilers that support precompilation, includes "wx.h".
|
// For compilers that support precompilation, includes "wx.h".
|
||||||
#include "wx/wxprec.h"
|
#include "wx/wxprec.h"
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
#ifdef __BORLANDC__
|
||||||
#pragma hdrstop
|
#pragma hdrstop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef WX_PRECOMP
|
#ifndef WX_PRECOMP
|
||||||
#include "wx/setup.h"
|
#include "wx/utils.h"
|
||||||
#include "wx/utils.h"
|
#include "wx/app.h"
|
||||||
#include "wx/app.h"
|
#include "wx/intl.h"
|
||||||
#include "wx/intl.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/log.h"
|
#include "wx/log.h"
|
||||||
|
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
#include "wx/process.h"
|
#include "wx/process.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "wx/msw/private.h"
|
#include "wx/msw/private.h"
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#if !defined(__GNUWIN32__) && !defined(__WXWINE__) && !defined(__SALFORDC__)
|
#if !defined(__GNUWIN32__) && !defined(__WXWINE__) && !defined(__SALFORDC__)
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#ifndef __MWERKS__
|
#ifndef __MWERKS__
|
||||||
#include <dos.h>
|
#include <dos.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUWIN32__
|
#if defined(__GNUWIN32__) && !defined(__TWIN32__)
|
||||||
#ifndef __TWIN32__
|
#include <sys/unistd.h>
|
||||||
#include <sys/unistd.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__WIN32__) && !defined(__WXWINE__)
|
#if defined(__WIN32__) && !defined(__WXWINE__)
|
||||||
@@ -71,9 +74,26 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// constants
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// this message is sent when the process we're waiting for terminates
|
// this message is sent when the process we're waiting for terminates
|
||||||
#define wxWM_PROC_TERMINATED (WM_USER + 10000)
|
#define wxWM_PROC_TERMINATED (WM_USER + 10000)
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// this module globals
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// we need to create a hidden window to receive the process termination
|
||||||
|
// notifications and for this we need a (Win) class name for it which we will
|
||||||
|
// register the first time it's needed
|
||||||
|
static const wxChar *gs_classForHiddenWindow = NULL;
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// private types
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// structure describing the process we're being waiting for
|
// structure describing the process we're being waiting for
|
||||||
struct wxExecuteData
|
struct wxExecuteData
|
||||||
{
|
{
|
||||||
@@ -96,6 +116,9 @@ public:
|
|||||||
bool state; // set to FALSE when the process finishes
|
bool state; // set to FALSE when the process finishes
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// implementation
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
#ifdef __WIN32__
|
#ifdef __WIN32__
|
||||||
static DWORD wxExecuteThread(wxExecuteData *data)
|
static DWORD wxExecuteThread(wxExecuteData *data)
|
||||||
@@ -150,8 +173,6 @@ LRESULT APIENTRY _EXPORT wxExecuteWindowCbk(HWND hWnd, UINT message,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern wxChar wxPanelClassName[];
|
|
||||||
|
|
||||||
long wxExecute(const wxString& command, bool sync, wxProcess *handler)
|
long wxExecute(const wxString& command, bool sync, wxProcess *handler)
|
||||||
{
|
{
|
||||||
wxCHECK_MSG( !!command, 0, wxT("empty command in wxExecute") );
|
wxCHECK_MSG( !!command, 0, wxT("empty command in wxExecute") );
|
||||||
@@ -242,17 +263,31 @@ long wxExecute(const wxString& command, bool sync, wxProcess *handler)
|
|||||||
if ( !::CloseHandle(pi.hThread) )
|
if ( !::CloseHandle(pi.hThread) )
|
||||||
wxLogLastError("CloseHandle(hThread)");
|
wxLogLastError("CloseHandle(hThread)");
|
||||||
|
|
||||||
|
if ( !gs_classForHiddenWindow )
|
||||||
|
{
|
||||||
|
gs_classForHiddenWindow = _T("wxHiddenWindow");
|
||||||
|
|
||||||
|
WNDCLASS wndclass;
|
||||||
|
wxZeroMemory(wndclass);
|
||||||
|
wndclass.lpfnWndProc = (WNDPROC)wxExecuteWindowCbk;
|
||||||
|
wndclass.hInstance = wxGetInstance();
|
||||||
|
wndclass.lpszClassName = gs_classForHiddenWindow;
|
||||||
|
|
||||||
|
if ( !::RegisterClass(&wndclass) )
|
||||||
|
{
|
||||||
|
wxLogLastError("RegisterClass(hidden window)");
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// create a hidden window to receive notification about process
|
// create a hidden window to receive notification about process
|
||||||
// termination
|
// termination
|
||||||
HWND hwnd = ::CreateWindow(wxPanelClassName, NULL, 0, 0, 0, 0, 0, NULL,
|
HWND hwnd = ::CreateWindow(gs_classForHiddenWindow, NULL,
|
||||||
|
0, 0, 0, 0, 0, NULL,
|
||||||
(HMENU)NULL, wxGetInstance(), 0);
|
(HMENU)NULL, wxGetInstance(), 0);
|
||||||
wxASSERT_MSG( hwnd, wxT("can't create a hidden window for wxExecute") );
|
wxASSERT_MSG( hwnd, wxT("can't create a hidden window for wxExecute") );
|
||||||
|
|
||||||
FARPROC ExecuteWindowInstance = MakeProcInstance((FARPROC)wxExecuteWindowCbk,
|
|
||||||
wxGetInstance());
|
|
||||||
|
|
||||||
::SetWindowLong(hwnd, GWL_WNDPROC, (LONG) ExecuteWindowInstance);
|
|
||||||
|
|
||||||
// Alloc data
|
// Alloc data
|
||||||
wxExecuteData *data = new wxExecuteData;
|
wxExecuteData *data = new wxExecuteData;
|
||||||
data->hProcess = pi.hProcess;
|
data->hProcess = pi.hProcess;
|
||||||
@@ -338,33 +373,3 @@ long wxExecute(char **argv, bool sync, wxProcess *handler)
|
|||||||
return wxExecute(command, sync, handler);
|
return wxExecute(command, sync, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxGetFullHostName(wxChar *buf, int maxSize)
|
|
||||||
{
|
|
||||||
#if defined(__WIN32__) && !defined(__TWIN32__)
|
|
||||||
DWORD nSize = maxSize ;
|
|
||||||
if ( !::GetComputerName(buf, &nSize) )
|
|
||||||
{
|
|
||||||
wxLogLastError("GetComputerName");
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
char *sysname;
|
|
||||||
const char *default_host = "noname";
|
|
||||||
static const char WX_SECTION[] = "wxWindows";
|
|
||||||
static const char eHOSTNAME[] = "HostName";
|
|
||||||
|
|
||||||
if ((sysname = getenv("SYSTEM_NAME")) == NULL) {
|
|
||||||
GetProfileString(WX_SECTION, eHOSTNAME, default_host, buf, maxSize - 1);
|
|
||||||
} else
|
|
||||||
strncpy(buf, sysname, maxSize - 1);
|
|
||||||
buf[maxSize] = '\0';
|
|
||||||
if ( *buf == '\0' )
|
|
||||||
{
|
|
||||||
wxLogLastError("GetComputerName");
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
@@ -685,7 +685,14 @@ wxThreadError wxThread::Resume()
|
|||||||
// exiting thread
|
// exiting thread
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
wxThread::ExitCode wxThread::Delete()
|
wxThread::ExitCode Wait()
|
||||||
|
{
|
||||||
|
wxFAIL_MSG("TODO");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxThreadError wxThread::Delete(ExitCode *rc)
|
||||||
{
|
{
|
||||||
if (IsPaused())
|
if (IsPaused())
|
||||||
Resume();
|
Resume();
|
||||||
@@ -745,7 +752,7 @@ wxThreadError wxThread::Kill()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxThread::Exit(void *status)
|
void wxThread::Exit(ExitCode status)
|
||||||
{
|
{
|
||||||
// first call user-level clean up code
|
// first call user-level clean up code
|
||||||
OnExit();
|
OnExit();
|
||||||
|
Reference in New Issue
Block a user