diff --git a/Makefile.in b/Makefile.in index d76dad451a..c845a955ea 100644 --- a/Makefile.in +++ b/Makefile.in @@ -2965,6 +2965,7 @@ COND_TOOLKIT_MSW_GUI_HDR = \ wx/msw/pen.h \ wx/msw/printdlg.h \ wx/msw/printwin.h \ + wx/msw/progdlg.h \ wx/msw/radiobox.h \ wx/msw/radiobut.h \ wx/msw/region.h \ @@ -3488,6 +3489,7 @@ COND_TOOLKIT_WINCE_GUI_HDR = \ wx/msw/pen.h \ wx/msw/printdlg.h \ wx/msw/printwin.h \ + wx/msw/progdlg.h \ wx/msw/radiobox.h \ wx/msw/radiobut.h \ wx/msw/region.h \ @@ -5377,6 +5379,7 @@ COND_TOOLKIT_MSW___GUI_SRC_OBJECTS = \ monodll_msw_notebook.o \ monodll_access.o \ monodll_msw_ownerdrw.o \ + monodll_progdlg.o \ monodll_msw_radiobox.o \ monodll_msw_radiobut.o \ monodll_richmsgdlg.o \ @@ -5613,6 +5616,7 @@ COND_TOOLKIT_WINCE___GUI_SRC_OBJECTS = \ monodll_msw_notebook.o \ monodll_access.o \ monodll_msw_ownerdrw.o \ + monodll_progdlg.o \ monodll_msw_radiobox.o \ monodll_msw_radiobut.o \ monodll_richmsgdlg.o \ @@ -7249,6 +7253,7 @@ COND_TOOLKIT_MSW___GUI_SRC_OBJECTS_1 = \ monolib_msw_notebook.o \ monolib_access.o \ monolib_msw_ownerdrw.o \ + monolib_progdlg.o \ monolib_msw_radiobox.o \ monolib_msw_radiobut.o \ monolib_richmsgdlg.o \ @@ -7485,6 +7490,7 @@ COND_TOOLKIT_WINCE___GUI_SRC_OBJECTS_1 = \ monolib_msw_notebook.o \ monolib_access.o \ monolib_msw_ownerdrw.o \ + monolib_progdlg.o \ monolib_msw_radiobox.o \ monolib_msw_radiobut.o \ monolib_richmsgdlg.o \ @@ -9308,6 +9314,7 @@ COND_TOOLKIT_MSW___GUI_SRC_OBJECTS_2 = \ coredll_msw_notebook.o \ coredll_access.o \ coredll_msw_ownerdrw.o \ + coredll_progdlg.o \ coredll_msw_radiobox.o \ coredll_msw_radiobut.o \ coredll_richmsgdlg.o \ @@ -9544,6 +9551,7 @@ COND_TOOLKIT_WINCE___GUI_SRC_OBJECTS_2 = \ coredll_msw_notebook.o \ coredll_access.o \ coredll_msw_ownerdrw.o \ + coredll_progdlg.o \ coredll_msw_radiobox.o \ coredll_msw_radiobut.o \ coredll_richmsgdlg.o \ @@ -10851,6 +10859,7 @@ COND_TOOLKIT_MSW___GUI_SRC_OBJECTS_3 = \ corelib_msw_notebook.o \ corelib_access.o \ corelib_msw_ownerdrw.o \ + corelib_progdlg.o \ corelib_msw_radiobox.o \ corelib_msw_radiobut.o \ corelib_richmsgdlg.o \ @@ -11087,6 +11096,7 @@ COND_TOOLKIT_WINCE___GUI_SRC_OBJECTS_3 = \ corelib_msw_notebook.o \ corelib_access.o \ corelib_msw_ownerdrw.o \ + corelib_progdlg.o \ corelib_msw_radiobox.o \ corelib_msw_radiobut.o \ corelib_richmsgdlg.o \ @@ -18888,6 +18898,12 @@ monodll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONODLL_ODEP) @COND_TOOLKIT_WINCE_USE_GUI_1_WXUNIV_0@monodll_msw_ownerdrw.o: $(srcdir)/src/msw/ownerdrw.cpp $(MONODLL_ODEP) @COND_TOOLKIT_WINCE_USE_GUI_1_WXUNIV_0@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/msw/ownerdrw.cpp +@COND_TOOLKIT_MSW_USE_GUI_1_WXUNIV_0@monodll_progdlg.o: $(srcdir)/src/msw/progdlg.cpp $(MONODLL_ODEP) +@COND_TOOLKIT_MSW_USE_GUI_1_WXUNIV_0@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/msw/progdlg.cpp + +@COND_TOOLKIT_WINCE_USE_GUI_1_WXUNIV_0@monodll_progdlg.o: $(srcdir)/src/msw/progdlg.cpp $(MONODLL_ODEP) +@COND_TOOLKIT_WINCE_USE_GUI_1_WXUNIV_0@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/msw/progdlg.cpp + @COND_TOOLKIT_MSW_USE_GUI_1_WXUNIV_0@monodll_msw_radiobox.o: $(srcdir)/src/msw/radiobox.cpp $(MONODLL_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1_WXUNIV_0@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/msw/radiobox.cpp @@ -24105,6 +24121,12 @@ monolib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_WINCE_USE_GUI_1_WXUNIV_0@monolib_msw_ownerdrw.o: $(srcdir)/src/msw/ownerdrw.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_WINCE_USE_GUI_1_WXUNIV_0@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/msw/ownerdrw.cpp +@COND_TOOLKIT_MSW_USE_GUI_1_WXUNIV_0@monolib_progdlg.o: $(srcdir)/src/msw/progdlg.cpp $(MONOLIB_ODEP) +@COND_TOOLKIT_MSW_USE_GUI_1_WXUNIV_0@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/msw/progdlg.cpp + +@COND_TOOLKIT_WINCE_USE_GUI_1_WXUNIV_0@monolib_progdlg.o: $(srcdir)/src/msw/progdlg.cpp $(MONOLIB_ODEP) +@COND_TOOLKIT_WINCE_USE_GUI_1_WXUNIV_0@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/msw/progdlg.cpp + @COND_TOOLKIT_MSW_USE_GUI_1_WXUNIV_0@monolib_msw_radiobox.o: $(srcdir)/src/msw/radiobox.cpp $(MONOLIB_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1_WXUNIV_0@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/msw/radiobox.cpp @@ -29508,6 +29530,12 @@ coredll_win32.o: $(srcdir)/src/univ/themes/win32.cpp $(COREDLL_ODEP) @COND_TOOLKIT_WINCE_USE_GUI_1_WXUNIV_0@coredll_msw_ownerdrw.o: $(srcdir)/src/msw/ownerdrw.cpp $(COREDLL_ODEP) @COND_TOOLKIT_WINCE_USE_GUI_1_WXUNIV_0@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/msw/ownerdrw.cpp +@COND_TOOLKIT_MSW_USE_GUI_1_WXUNIV_0@coredll_progdlg.o: $(srcdir)/src/msw/progdlg.cpp $(COREDLL_ODEP) +@COND_TOOLKIT_MSW_USE_GUI_1_WXUNIV_0@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/msw/progdlg.cpp + +@COND_TOOLKIT_WINCE_USE_GUI_1_WXUNIV_0@coredll_progdlg.o: $(srcdir)/src/msw/progdlg.cpp $(COREDLL_ODEP) +@COND_TOOLKIT_WINCE_USE_GUI_1_WXUNIV_0@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/msw/progdlg.cpp + @COND_TOOLKIT_MSW_USE_GUI_1_WXUNIV_0@coredll_msw_radiobox.o: $(srcdir)/src/msw/radiobox.cpp $(COREDLL_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1_WXUNIV_0@ $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/msw/radiobox.cpp @@ -33426,6 +33454,12 @@ corelib_win32.o: $(srcdir)/src/univ/themes/win32.cpp $(CORELIB_ODEP) @COND_TOOLKIT_WINCE_USE_GUI_1_WXUNIV_0@corelib_msw_ownerdrw.o: $(srcdir)/src/msw/ownerdrw.cpp $(CORELIB_ODEP) @COND_TOOLKIT_WINCE_USE_GUI_1_WXUNIV_0@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/msw/ownerdrw.cpp +@COND_TOOLKIT_MSW_USE_GUI_1_WXUNIV_0@corelib_progdlg.o: $(srcdir)/src/msw/progdlg.cpp $(CORELIB_ODEP) +@COND_TOOLKIT_MSW_USE_GUI_1_WXUNIV_0@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/msw/progdlg.cpp + +@COND_TOOLKIT_WINCE_USE_GUI_1_WXUNIV_0@corelib_progdlg.o: $(srcdir)/src/msw/progdlg.cpp $(CORELIB_ODEP) +@COND_TOOLKIT_WINCE_USE_GUI_1_WXUNIV_0@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/msw/progdlg.cpp + @COND_TOOLKIT_MSW_USE_GUI_1_WXUNIV_0@corelib_msw_radiobox.o: $(srcdir)/src/msw/radiobox.cpp $(CORELIB_ODEP) @COND_TOOLKIT_MSW_USE_GUI_1_WXUNIV_0@ $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/msw/radiobox.cpp diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index 57af655284..0739188eea 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -1718,6 +1718,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/msw/notebook.cpp src/msw/ole/access.cpp src/msw/ownerdrw.cpp + src/msw/progdlg.cpp src/msw/radiobox.cpp src/msw/radiobut.cpp src/msw/richmsgdlg.cpp @@ -1802,6 +1803,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/msw/pen.h wx/msw/printdlg.h wx/msw/printwin.h + wx/msw/progdlg.h wx/msw/radiobox.h wx/msw/radiobut.h wx/msw/region.h diff --git a/build/msw/makefile.bcc b/build/msw/makefile.bcc index b97cf98576..04e102042f 100644 --- a/build/msw/makefile.bcc +++ b/build/msw/makefile.bcc @@ -1750,11 +1750,12 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_msgdlg.obj \ $(OBJS)\monodll_nativdlg.obj \ $(OBJS)\monodll_nativewin.obj \ - $(OBJS)\monodll_msw_notebook.obj \ - $(OBJS)\monodll_access.obj \ - $(OBJS)\monodll_ownerdrw.obj \ - $(OBJS)\monodll_msw_radiobox.obj \ - $(OBJS)\monodll_msw_radiobut.obj \ + $(OBJS)\monodll_msw_notebook.obj \ + $(OBJS)\monodll_access.obj \ + $(OBJS)\monodll_ownerdrw.obj \ + $(OBJS)\monodll_progdlg.obj \ + $(OBJS)\monodll_msw_radiobox.obj \ + $(OBJS)\monodll_msw_radiobut.obj \ $(OBJS)\monodll_richmsgdlg.obj \ $(OBJS)\monodll_msw_scrolbar.obj \ $(OBJS)\monodll_msw_slider.obj \ @@ -2469,11 +2470,12 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_msgdlg.obj \ $(OBJS)\monolib_nativdlg.obj \ $(OBJS)\monolib_nativewin.obj \ - $(OBJS)\monolib_msw_notebook.obj \ - $(OBJS)\monolib_access.obj \ - $(OBJS)\monolib_ownerdrw.obj \ - $(OBJS)\monolib_msw_radiobox.obj \ - $(OBJS)\monolib_msw_radiobut.obj \ + $(OBJS)\monolib_msw_notebook.obj \ + $(OBJS)\monolib_access.obj \ + $(OBJS)\monolib_ownerdrw.obj \ + $(OBJS)\monolib_progdlg.obj \ + $(OBJS)\monolib_msw_radiobox.obj \ + $(OBJS)\monolib_msw_radiobut.obj \ $(OBJS)\monolib_richmsgdlg.obj \ $(OBJS)\monolib_msw_scrolbar.obj \ $(OBJS)\monolib_msw_slider.obj \ @@ -3079,11 +3081,12 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_msgdlg.obj \ $(OBJS)\coredll_nativdlg.obj \ $(OBJS)\coredll_nativewin.obj \ - $(OBJS)\coredll_msw_notebook.obj \ - $(OBJS)\coredll_access.obj \ - $(OBJS)\coredll_ownerdrw.obj \ - $(OBJS)\coredll_msw_radiobox.obj \ - $(OBJS)\coredll_msw_radiobut.obj \ + $(OBJS)\coredll_msw_notebook.obj \ + $(OBJS)\coredll_access.obj \ + $(OBJS)\coredll_ownerdrw.obj \ + $(OBJS)\coredll_progdlg.obj \ + $(OBJS)\coredll_msw_radiobox.obj \ + $(OBJS)\coredll_msw_radiobut.obj \ $(OBJS)\coredll_richmsgdlg.obj \ $(OBJS)\coredll_msw_scrolbar.obj \ $(OBJS)\coredll_msw_slider.obj \ @@ -3581,11 +3584,12 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_msgdlg.obj \ $(OBJS)\corelib_nativdlg.obj \ $(OBJS)\corelib_nativewin.obj \ - $(OBJS)\corelib_msw_notebook.obj \ - $(OBJS)\corelib_access.obj \ - $(OBJS)\corelib_ownerdrw.obj \ - $(OBJS)\corelib_msw_radiobox.obj \ - $(OBJS)\corelib_msw_radiobut.obj \ + $(OBJS)\corelib_msw_notebook.obj \ + $(OBJS)\corelib_access.obj \ + $(OBJS)\corelib_ownerdrw.obj \ + $(OBJS)\corelib_progdlg.obj \ + $(OBJS)\corelib_msw_radiobox.obj \ + $(OBJS)\corelib_msw_radiobut.obj \ $(OBJS)\corelib_richmsgdlg.obj \ $(OBJS)\corelib_msw_scrolbar.obj \ $(OBJS)\corelib_msw_slider.obj \ @@ -6188,6 +6192,9 @@ $(OBJS)\monodll_access.obj: ..\..\src\msw\ole\access.cpp $(OBJS)\monodll_ownerdrw.obj: ..\..\src\msw\ownerdrw.cpp $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\ownerdrw.cpp +$(OBJS)\monodll_progdlg.obj: ..\..\src\msw\progdlg.cpp + $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\progdlg.cpp + $(OBJS)\monodll_msw_radiobox.obj: ..\..\src\msw\radiobox.cpp $(CXX) -q -c -P -o$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\radiobox.cpp @@ -8420,6 +8427,9 @@ $(OBJS)\monolib_access.obj: ..\..\src\msw\ole\access.cpp $(OBJS)\monolib_ownerdrw.obj: ..\..\src\msw\ownerdrw.cpp $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\ownerdrw.cpp +$(OBJS)\monolib_progdlg.obj: ..\..\src\msw\progdlg.cpp + $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\progdlg.cpp + $(OBJS)\monolib_msw_radiobox.obj: ..\..\src\msw\radiobox.cpp $(CXX) -q -c -P -o$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\radiobox.cpp @@ -11060,6 +11070,9 @@ $(OBJS)\coredll_access.obj: ..\..\src\msw\ole\access.cpp $(OBJS)\coredll_ownerdrw.obj: ..\..\src\msw\ownerdrw.cpp $(CXX) -q -c -P -o$@ $(COREDLL_CXXFLAGS) ..\..\src\msw\ownerdrw.cpp +$(OBJS)\coredll_progdlg.obj: ..\..\src\msw\progdlg.cpp + $(CXX) -q -c -P -o$@ $(COREDLL_CXXFLAGS) ..\..\src\msw\progdlg.cpp + $(OBJS)\coredll_msw_radiobox.obj: ..\..\src\msw\radiobox.cpp $(CXX) -q -c -P -o$@ $(COREDLL_CXXFLAGS) ..\..\src\msw\radiobox.cpp @@ -12367,6 +12380,9 @@ $(OBJS)\corelib_access.obj: ..\..\src\msw\ole\access.cpp $(OBJS)\corelib_ownerdrw.obj: ..\..\src\msw\ownerdrw.cpp $(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) ..\..\src\msw\ownerdrw.cpp +$(OBJS)\corelib_progdlg.obj: ..\..\src\msw\progdlg.cpp + $(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) ..\..\src\msw\progdlg.cpp + $(OBJS)\corelib_msw_radiobox.obj: ..\..\src\msw\radiobox.cpp $(CXX) -q -c -P -o$@ $(CORELIB_CXXFLAGS) ..\..\src\msw\radiobox.cpp diff --git a/build/msw/makefile.gcc b/build/msw/makefile.gcc index 17486f80eb..9458aadbd9 100644 --- a/build/msw/makefile.gcc +++ b/build/msw/makefile.gcc @@ -1761,11 +1761,12 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_msgdlg.o \ $(OBJS)\monodll_nativdlg.o \ $(OBJS)\monodll_nativewin.o \ - $(OBJS)\monodll_msw_notebook.o \ - $(OBJS)\monodll_access.o \ - $(OBJS)\monodll_ownerdrw.o \ - $(OBJS)\monodll_msw_radiobox.o \ - $(OBJS)\monodll_msw_radiobut.o \ + $(OBJS)\monodll_msw_notebook.o \ + $(OBJS)\monodll_access.o \ + $(OBJS)\monodll_ownerdrw.o \ + $(OBJS)\monodll_progdlg.o \ + $(OBJS)\monodll_msw_radiobox.o \ + $(OBJS)\monodll_msw_radiobut.o \ $(OBJS)\monodll_richmsgdlg.o \ $(OBJS)\monodll_msw_scrolbar.o \ $(OBJS)\monodll_msw_slider.o \ @@ -2486,11 +2487,12 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_msgdlg.o \ $(OBJS)\monolib_nativdlg.o \ $(OBJS)\monolib_nativewin.o \ - $(OBJS)\monolib_msw_notebook.o \ - $(OBJS)\monolib_access.o \ - $(OBJS)\monolib_ownerdrw.o \ - $(OBJS)\monolib_msw_radiobox.o \ - $(OBJS)\monolib_msw_radiobut.o \ + $(OBJS)\monolib_msw_notebook.o \ + $(OBJS)\monolib_access.o \ + $(OBJS)\monolib_ownerdrw.o \ + $(OBJS)\monolib_progdlg.o \ + $(OBJS)\monolib_msw_radiobox.o \ + $(OBJS)\monolib_msw_radiobut.o \ $(OBJS)\monolib_richmsgdlg.o \ $(OBJS)\monolib_msw_scrolbar.o \ $(OBJS)\monolib_msw_slider.o \ @@ -3112,11 +3114,12 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_msgdlg.o \ $(OBJS)\coredll_nativdlg.o \ $(OBJS)\coredll_nativewin.o \ - $(OBJS)\coredll_msw_notebook.o \ - $(OBJS)\coredll_access.o \ - $(OBJS)\coredll_ownerdrw.o \ - $(OBJS)\coredll_msw_radiobox.o \ - $(OBJS)\coredll_msw_radiobut.o \ + $(OBJS)\coredll_msw_notebook.o \ + $(OBJS)\coredll_access.o \ + $(OBJS)\coredll_ownerdrw.o \ + $(OBJS)\coredll_progdlg.o \ + $(OBJS)\coredll_msw_radiobox.o \ + $(OBJS)\coredll_msw_radiobut.o \ $(OBJS)\coredll_richmsgdlg.o \ $(OBJS)\coredll_msw_scrolbar.o \ $(OBJS)\coredll_msw_slider.o \ @@ -3622,11 +3625,12 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_msgdlg.o \ $(OBJS)\corelib_nativdlg.o \ $(OBJS)\corelib_nativewin.o \ - $(OBJS)\corelib_msw_notebook.o \ - $(OBJS)\corelib_access.o \ - $(OBJS)\corelib_ownerdrw.o \ - $(OBJS)\corelib_msw_radiobox.o \ - $(OBJS)\corelib_msw_radiobut.o \ + $(OBJS)\corelib_msw_notebook.o \ + $(OBJS)\corelib_access.o \ + $(OBJS)\corelib_ownerdrw.o \ + $(OBJS)\corelib_progdlg.o \ + $(OBJS)\corelib_msw_radiobox.o \ + $(OBJS)\corelib_msw_radiobut.o \ $(OBJS)\corelib_richmsgdlg.o \ $(OBJS)\corelib_msw_scrolbar.o \ $(OBJS)\corelib_msw_slider.o \ @@ -6338,6 +6342,9 @@ $(OBJS)\monodll_access.o: ../../src/msw/ole/access.cpp $(OBJS)\monodll_ownerdrw.o: ../../src/msw/ownerdrw.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\monodll_progdlg.o: ../../src/msw/progdlg.cpp + $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\monodll_msw_radiobox.o: ../../src/msw/radiobox.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< @@ -8570,6 +8577,9 @@ $(OBJS)\monolib_access.o: ../../src/msw/ole/access.cpp $(OBJS)\monolib_ownerdrw.o: ../../src/msw/ownerdrw.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\monolib_progdlg.o: ../../src/msw/progdlg.cpp + $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\monolib_msw_radiobox.o: ../../src/msw/radiobox.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< @@ -11210,6 +11220,9 @@ $(OBJS)\coredll_access.o: ../../src/msw/ole/access.cpp $(OBJS)\coredll_ownerdrw.o: ../../src/msw/ownerdrw.cpp $(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\coredll_progdlg.o: ../../src/msw/progdlg.cpp + $(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\coredll_msw_radiobox.o: ../../src/msw/radiobox.cpp $(CXX) -c -o $@ $(COREDLL_CXXFLAGS) $(CPPDEPS) $< @@ -12517,6 +12530,9 @@ $(OBJS)\corelib_access.o: ../../src/msw/ole/access.cpp $(OBJS)\corelib_ownerdrw.o: ../../src/msw/ownerdrw.cpp $(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\corelib_progdlg.o: ../../src/msw/progdlg.cpp + $(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\corelib_msw_radiobox.o: ../../src/msw/radiobox.cpp $(CXX) -c -o $@ $(CORELIB_CXXFLAGS) $(CPPDEPS) $< diff --git a/build/msw/makefile.vc b/build/msw/makefile.vc index bf7554dc41..7c49f77c47 100644 --- a/build/msw/makefile.vc +++ b/build/msw/makefile.vc @@ -1958,11 +1958,12 @@ ____CORE_SRC_FILENAMES_OBJECTS = \ $(OBJS)\monodll_msgdlg.obj \ $(OBJS)\monodll_nativdlg.obj \ $(OBJS)\monodll_nativewin.obj \ - $(OBJS)\monodll_msw_notebook.obj \ - $(OBJS)\monodll_access.obj \ - $(OBJS)\monodll_ownerdrw.obj \ - $(OBJS)\monodll_msw_radiobox.obj \ - $(OBJS)\monodll_msw_radiobut.obj \ + $(OBJS)\monodll_msw_notebook.obj \ + $(OBJS)\monodll_access.obj \ + $(OBJS)\monodll_ownerdrw.obj \ + $(OBJS)\monodll_progdlg.obj \ + $(OBJS)\monodll_msw_radiobox.obj \ + $(OBJS)\monodll_msw_radiobut.obj \ $(OBJS)\monodll_richmsgdlg.obj \ $(OBJS)\monodll_msw_scrolbar.obj \ $(OBJS)\monodll_msw_slider.obj \ @@ -2683,11 +2684,12 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = \ $(OBJS)\monolib_msgdlg.obj \ $(OBJS)\monolib_nativdlg.obj \ $(OBJS)\monolib_nativewin.obj \ - $(OBJS)\monolib_msw_notebook.obj \ - $(OBJS)\monolib_access.obj \ - $(OBJS)\monolib_ownerdrw.obj \ - $(OBJS)\monolib_msw_radiobox.obj \ - $(OBJS)\monolib_msw_radiobut.obj \ + $(OBJS)\monolib_msw_notebook.obj \ + $(OBJS)\monolib_access.obj \ + $(OBJS)\monolib_ownerdrw.obj \ + $(OBJS)\monolib_progdlg.obj \ + $(OBJS)\monolib_msw_radiobox.obj \ + $(OBJS)\monolib_msw_radiobut.obj \ $(OBJS)\monolib_richmsgdlg.obj \ $(OBJS)\monolib_msw_scrolbar.obj \ $(OBJS)\monolib_msw_slider.obj \ @@ -3359,11 +3361,12 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = \ $(OBJS)\coredll_msgdlg.obj \ $(OBJS)\coredll_nativdlg.obj \ $(OBJS)\coredll_nativewin.obj \ - $(OBJS)\coredll_msw_notebook.obj \ - $(OBJS)\coredll_access.obj \ - $(OBJS)\coredll_ownerdrw.obj \ - $(OBJS)\coredll_msw_radiobox.obj \ - $(OBJS)\coredll_msw_radiobut.obj \ + $(OBJS)\coredll_msw_notebook.obj \ + $(OBJS)\coredll_access.obj \ + $(OBJS)\coredll_ownerdrw.obj \ + $(OBJS)\coredll_progdlg.obj \ + $(OBJS)\coredll_msw_radiobox.obj \ + $(OBJS)\coredll_msw_radiobut.obj \ $(OBJS)\coredll_richmsgdlg.obj \ $(OBJS)\coredll_msw_scrolbar.obj \ $(OBJS)\coredll_msw_slider.obj \ @@ -3867,11 +3870,12 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = \ $(OBJS)\corelib_msgdlg.obj \ $(OBJS)\corelib_nativdlg.obj \ $(OBJS)\corelib_nativewin.obj \ - $(OBJS)\corelib_msw_notebook.obj \ - $(OBJS)\corelib_access.obj \ - $(OBJS)\corelib_ownerdrw.obj \ - $(OBJS)\corelib_msw_radiobox.obj \ - $(OBJS)\corelib_msw_radiobut.obj \ + $(OBJS)\corelib_msw_notebook.obj \ + $(OBJS)\corelib_access.obj \ + $(OBJS)\corelib_ownerdrw.obj \ + $(OBJS)\corelib_progdlg.obj \ + $(OBJS)\corelib_msw_radiobox.obj \ + $(OBJS)\corelib_msw_radiobut.obj \ $(OBJS)\corelib_richmsgdlg.obj \ $(OBJS)\corelib_msw_scrolbar.obj \ $(OBJS)\corelib_msw_slider.obj \ @@ -6768,6 +6772,9 @@ $(OBJS)\monodll_access.obj: ..\..\src\msw\ole\access.cpp $(OBJS)\monodll_ownerdrw.obj: ..\..\src\msw\ownerdrw.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\ownerdrw.cpp +$(OBJS)\monodll_progdlg.obj: ..\..\src\msw\progdlg.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\progdlg.cpp + $(OBJS)\monodll_msw_radiobox.obj: ..\..\src\msw\radiobox.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\radiobox.cpp @@ -9000,6 +9007,9 @@ $(OBJS)\monolib_access.obj: ..\..\src\msw\ole\access.cpp $(OBJS)\monolib_ownerdrw.obj: ..\..\src\msw\ownerdrw.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\ownerdrw.cpp +$(OBJS)\monolib_progdlg.obj: ..\..\src\msw\progdlg.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\progdlg.cpp + $(OBJS)\monolib_msw_radiobox.obj: ..\..\src\msw\radiobox.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\radiobox.cpp @@ -11640,6 +11650,9 @@ $(OBJS)\coredll_access.obj: ..\..\src\msw\ole\access.cpp $(OBJS)\coredll_ownerdrw.obj: ..\..\src\msw\ownerdrw.cpp $(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) ..\..\src\msw\ownerdrw.cpp +$(OBJS)\coredll_progdlg.obj: ..\..\src\msw\progdlg.cpp + $(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) ..\..\src\msw\progdlg.cpp + $(OBJS)\coredll_msw_radiobox.obj: ..\..\src\msw\radiobox.cpp $(CXX) /c /nologo /TP /Fo$@ $(COREDLL_CXXFLAGS) ..\..\src\msw\radiobox.cpp @@ -12947,6 +12960,9 @@ $(OBJS)\corelib_access.obj: ..\..\src\msw\ole\access.cpp $(OBJS)\corelib_ownerdrw.obj: ..\..\src\msw\ownerdrw.cpp $(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) ..\..\src\msw\ownerdrw.cpp +$(OBJS)\corelib_progdlg.obj: ..\..\src\msw\progdlg.cpp + $(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) ..\..\src\msw\progdlg.cpp + $(OBJS)\corelib_msw_radiobox.obj: ..\..\src\msw\radiobox.cpp $(CXX) /c /nologo /TP /Fo$@ $(CORELIB_CXXFLAGS) ..\..\src\msw\radiobox.cpp diff --git a/build/msw/makefile.wat b/build/msw/makefile.wat index 5e9414833e..b20f5dc887 100644 --- a/build/msw/makefile.wat +++ b/build/msw/makefile.wat @@ -321,11 +321,12 @@ ____CORE_SRC_FILENAMES_OBJECTS = & $(OBJS)\monodll_msgdlg.obj & $(OBJS)\monodll_nativdlg.obj & $(OBJS)\monodll_nativewin.obj & - $(OBJS)\monodll_msw_notebook.obj & - $(OBJS)\monodll_access.obj & - $(OBJS)\monodll_ownerdrw.obj & - $(OBJS)\monodll_msw_radiobox.obj & - $(OBJS)\monodll_msw_radiobut.obj & + $(OBJS)\monodll_msw_notebook.obj & + $(OBJS)\monodll_access.obj & + $(OBJS)\monodll_ownerdrw.obj & + $(OBJS)\monodll_progdlg.obj & + $(OBJS)\monodll_msw_radiobox.obj & + $(OBJS)\monodll_msw_radiobut.obj & $(OBJS)\monodll_richmsgdlg.obj & $(OBJS)\monodll_msw_scrolbar.obj & $(OBJS)\monodll_msw_slider.obj & @@ -1051,11 +1052,12 @@ ____CORE_SRC_FILENAMES_1_OBJECTS = & $(OBJS)\monolib_msgdlg.obj & $(OBJS)\monolib_nativdlg.obj & $(OBJS)\monolib_nativewin.obj & - $(OBJS)\monolib_msw_notebook.obj & - $(OBJS)\monolib_access.obj & - $(OBJS)\monolib_ownerdrw.obj & - $(OBJS)\monolib_msw_radiobox.obj & - $(OBJS)\monolib_msw_radiobut.obj & + $(OBJS)\monolib_msw_notebook.obj & + $(OBJS)\monolib_access.obj & + $(OBJS)\monolib_ownerdrw.obj & + $(OBJS)\monolib_progdlg.obj & + $(OBJS)\monolib_msw_radiobox.obj & + $(OBJS)\monolib_msw_radiobut.obj & $(OBJS)\monolib_richmsgdlg.obj & $(OBJS)\monolib_msw_scrolbar.obj & $(OBJS)\monolib_msw_slider.obj & @@ -1688,11 +1690,12 @@ ____CORE_SRC_FILENAMES_2_OBJECTS = & $(OBJS)\coredll_msgdlg.obj & $(OBJS)\coredll_nativdlg.obj & $(OBJS)\coredll_nativewin.obj & - $(OBJS)\coredll_msw_notebook.obj & - $(OBJS)\coredll_access.obj & - $(OBJS)\coredll_ownerdrw.obj & - $(OBJS)\coredll_msw_radiobox.obj & - $(OBJS)\coredll_msw_radiobut.obj & + $(OBJS)\coredll_msw_notebook.obj & + $(OBJS)\coredll_access.obj & + $(OBJS)\coredll_ownerdrw.obj & + $(OBJS)\coredll_progdlg.obj & + $(OBJS)\coredll_msw_radiobox.obj & + $(OBJS)\coredll_msw_radiobut.obj & $(OBJS)\coredll_richmsgdlg.obj & $(OBJS)\coredll_msw_scrolbar.obj & $(OBJS)\coredll_msw_slider.obj & @@ -2200,11 +2203,12 @@ ____CORE_SRC_FILENAMES_3_OBJECTS = & $(OBJS)\corelib_msgdlg.obj & $(OBJS)\corelib_nativdlg.obj & $(OBJS)\corelib_nativewin.obj & - $(OBJS)\corelib_msw_notebook.obj & - $(OBJS)\corelib_access.obj & - $(OBJS)\corelib_ownerdrw.obj & - $(OBJS)\corelib_msw_radiobox.obj & - $(OBJS)\corelib_msw_radiobut.obj & + $(OBJS)\corelib_msw_notebook.obj & + $(OBJS)\corelib_access.obj & + $(OBJS)\corelib_ownerdrw.obj & + $(OBJS)\corelib_progdlg.obj & + $(OBJS)\corelib_msw_radiobox.obj & + $(OBJS)\corelib_msw_radiobut.obj & $(OBJS)\corelib_richmsgdlg.obj & $(OBJS)\corelib_msw_scrolbar.obj & $(OBJS)\corelib_msw_slider.obj & @@ -6597,6 +6601,9 @@ $(OBJS)\monodll_access.obj : .AUTODEPEND ..\..\src\msw\ole\access.cpp $(OBJS)\monodll_ownerdrw.obj : .AUTODEPEND ..\..\src\msw\ownerdrw.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< +$(OBJS)\monodll_progdlg.obj : .AUTODEPEND ..\..\src\msw\progdlg.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< + $(OBJS)\monodll_msw_radiobox.obj : .AUTODEPEND ..\..\src\msw\radiobox.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONODLL_CXXFLAGS) $< @@ -8829,6 +8836,9 @@ $(OBJS)\monolib_access.obj : .AUTODEPEND ..\..\src\msw\ole\access.cpp $(OBJS)\monolib_ownerdrw.obj : .AUTODEPEND ..\..\src\msw\ownerdrw.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< +$(OBJS)\monolib_progdlg.obj : .AUTODEPEND ..\..\src\msw\progdlg.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< + $(OBJS)\monolib_msw_radiobox.obj : .AUTODEPEND ..\..\src\msw\radiobox.cpp $(CXX) -bt=nt -zq -fo=$^@ $(MONOLIB_CXXFLAGS) $< @@ -11469,6 +11479,9 @@ $(OBJS)\coredll_access.obj : .AUTODEPEND ..\..\src\msw\ole\access.cpp $(OBJS)\coredll_ownerdrw.obj : .AUTODEPEND ..\..\src\msw\ownerdrw.cpp $(CXX) -bt=nt -zq -fo=$^@ $(COREDLL_CXXFLAGS) $< +$(OBJS)\coredll_progdlg.obj : .AUTODEPEND ..\..\src\msw\progdlg.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(COREDLL_CXXFLAGS) $< + $(OBJS)\coredll_msw_radiobox.obj : .AUTODEPEND ..\..\src\msw\radiobox.cpp $(CXX) -bt=nt -zq -fo=$^@ $(COREDLL_CXXFLAGS) $< @@ -12776,6 +12789,9 @@ $(OBJS)\corelib_access.obj : .AUTODEPEND ..\..\src\msw\ole\access.cpp $(OBJS)\corelib_ownerdrw.obj : .AUTODEPEND ..\..\src\msw\ownerdrw.cpp $(CXX) -bt=nt -zq -fo=$^@ $(CORELIB_CXXFLAGS) $< +$(OBJS)\corelib_progdlg.obj : .AUTODEPEND ..\..\src\msw\progdlg.cpp + $(CXX) -bt=nt -zq -fo=$^@ $(CORELIB_CXXFLAGS) $< + $(OBJS)\corelib_msw_radiobox.obj : .AUTODEPEND ..\..\src\msw\radiobox.cpp $(CXX) -bt=nt -zq -fo=$^@ $(CORELIB_CXXFLAGS) $< diff --git a/build/msw/wx_core.dsp b/build/msw/wx_core.dsp index 8bff982d6c..ccd8920a42 100644 --- a/build/msw/wx_core.dsp +++ b/build/msw/wx_core.dsp @@ -2025,6 +2025,41 @@ SOURCE=..\..\src\msw\printwin.cpp # End Source File # Begin Source File +SOURCE=..\..\src\msw\progdlg.cpp + +!IF "$(CFG)" == "core - Win32 DLL Universal Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "core - Win32 DLL Universal Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "core - Win32 DLL Release" + + +!ELSEIF "$(CFG)" == "core - Win32 DLL Debug" + + +!ELSEIF "$(CFG)" == "core - Win32 Universal Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "core - Win32 Universal Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "core - Win32 Release" + + +!ELSEIF "$(CFG)" == "core - Win32 Debug" + + +!ENDIF + +# End Source File +# Begin Source File + SOURCE=..\..\src\msw\radiobox.cpp !IF "$(CFG)" == "core - Win32 DLL Universal Release" @@ -5162,6 +5197,10 @@ SOURCE=..\..\include\wx\msw\printwin.h # End Source File # Begin Source File +SOURCE=..\..\include\wx\msw\progdlg.h +# End Source File +# Begin Source File + SOURCE=..\..\include\wx\msw\radiobox.h # End Source File # Begin Source File diff --git a/build/msw/wx_vc7_core.vcproj b/build/msw/wx_vc7_core.vcproj index 033941da73..450f6adb30 100644 --- a/build/msw/wx_vc7_core.vcproj +++ b/build/msw/wx_vc7_core.vcproj @@ -1901,6 +1901,21 @@ RelativePath="..\..\src\msw\printwin.cpp"> + + + + + + @@ -4474,6 +4489,9 @@ RelativePath="..\..\include\wx\msw\printwin.h"> + + + + + + + + + + diff --git a/build/msw/wx_vc9_core.vcproj b/build/msw/wx_vc9_core.vcproj index 7511147f48..5efe4dd593 100644 --- a/build/msw/wx_vc9_core.vcproj +++ b/build/msw/wx_vc9_core.vcproj @@ -2564,6 +2564,26 @@ > + + + + + + + + diff --git a/docs/changes.txt b/docs/changes.txt index 8d94d5c37c..7e831c5ba7 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -403,13 +403,6 @@ Major new features in this release 2.9.2: ------ -MSW: - -- Fix Cygwin 1.7 build (David Gangola). -- Native wxHyperlinkCtrl implementation (Rickard Westerlund, GSoC 2010 project). -- Allow using wxDC::DrawText() with multiline texts. -- Fix wxBitmapButton best size determination broken in 2.9.1. - All (GUI): - Added wxRichMessageDialog (Rickard Westerlund, GSoC 2010 project). @@ -420,6 +413,15 @@ All (GUI): - wxRibbon: added EVT_RIBBONGALLERY_CLICKED event (John Roberts). - Add support for CP-866 encoding to wxEncodingConverter (madnut). +MSW: + +- Native implementation of wxHyperlinkCtrl and wxProgressDialog under modern + Windows versions (Rickard Westerlund, GSoC 2010 project). +- Fix Cygwin 1.7 build (David Gangola). +- Allow using wxDC::DrawText() with multiline texts. +- Fix wxBitmapButton best size determination broken in 2.9.1. + + 2.9.1: ------ diff --git a/include/wx/generic/progdlgg.h b/include/wx/generic/progdlgg.h index ce05dd40f8..cca4526f6c 100644 --- a/include/wx/generic/progdlgg.h +++ b/include/wx/generic/progdlgg.h @@ -1,6 +1,6 @@ /////////////////////////////////////////////////////////////////////////////// // Name: progdlgg.h -// Purpose: wxProgressDialog class +// Purpose: wxGenericProgressDialog class // Author: Karsten Ballueder // Modified by: Francesco Montorsi // Created: 09.05.1999 @@ -12,11 +12,6 @@ #ifndef __PROGDLGH_G__ #define __PROGDLGH_G__ -#include "wx/defs.h" -#include "wx/progdlg.h" - -#if wxUSE_PROGRESSDLG - #include "wx/dialog.h" class WXDLLIMPEXP_FWD_CORE wxButton; @@ -27,15 +22,15 @@ class WXDLLIMPEXP_FWD_CORE wxStaticText; Progress dialog which shows a moving progress bar. Taken from the Mahogany project. */ -class WXDLLIMPEXP_CORE wxProgressDialog : public wxDialog +class WXDLLIMPEXP_CORE wxGenericProgressDialog : public wxDialog { public: - wxProgressDialog(const wxString& title, const wxString& message, - int maximum = 100, - wxWindow *parent = NULL, - int style = wxPD_APP_MODAL | wxPD_AUTO_HIDE); + wxGenericProgressDialog(const wxString& title, const wxString& message, + int maximum = 100, + wxWindow *parent = NULL, + int style = wxPD_APP_MODAL | wxPD_AUTO_HIDE); - virtual ~wxProgressDialog(); + virtual ~wxGenericProgressDialog(); virtual bool Update(int value, const wxString& newmsg = wxEmptyString, bool *skip = NULL); virtual bool Pulse(const wxString& newmsg = wxEmptyString, bool *skip = NULL); @@ -58,7 +53,43 @@ public: virtual bool Show( bool show = true ); + // This enum is an implementation detail and should not be used + // by user code. + enum ProgressDialogState + { + Uncancelable = -1, // dialog can't be canceled + Canceled, // can be cancelled and, in fact, was + Continue, // can be cancelled but wasn't + Finished // finished, waiting to be removed from screen + }; + protected: + // This ctor is used by the native MSW implementation only. + wxGenericProgressDialog(wxWindow *parent, int maximum, int style); + + void Create(const wxString& title, + const wxString& message, + int maximum, + wxWindow *parent, + int style); + + // Return the labels to use for showing the elapsed/estimated/remaining + // times respectively. + static wxString GetElapsedLabel() { return _("Elapsed time:"); } + static wxString GetEstimatedLabel() { return _("Estimated time:"); } + static wxString GetRemainingLabel() { return _("Remaining time:"); } + + + // Updates estimated times from a given progress bar value and stores the + // results in provided arguments. + void UpdateTimeEstimates(int value, + unsigned long &elapsedTime, + unsigned long &estimatedTime, + unsigned long &remainingTime); + + // Converts seconds to HH:mm:ss format. + static wxString GetFormattedTime(unsigned long timeInSec); + // callback for optional abort button void OnCancel(wxCommandEvent&); @@ -68,11 +99,43 @@ protected: // callback to disable "hard" window closing void OnClose(wxCloseEvent&); + // called to disable the other windows while this dialog is shown + void DisableOtherWindows(); + // must be called to reenable the other windows temporarily disabled while // the dialog was shown void ReenableOtherWindows(); + // return the top level parent window of this dialog (may be NULL) + wxWindow *GetTopParent() const { return m_parentTop; } + + + // continue processing or not (return value for Update()) + ProgressDialogState m_state; + + // the maximum value + int m_maximum; + +#if defined(__WXMSW__ ) || defined(__WXPM__) + // the factor we use to always keep the value in 16 bit range as the native + // control only supports ranges from 0 to 65,535 + size_t m_factor; +#endif // __WXMSW__ + + // time when the dialog was created + unsigned long m_timeStart; + // time when the dialog was closed or cancelled + unsigned long m_timeStop; + // time between the moment the dialog was closed/cancelled and resume + unsigned long m_break; + private: + // update the label to show the given time (in seconds) + static void SetTimeLabel(unsigned long val, wxStaticText *label); + + // common part of all ctors + void Init(wxWindow *parent, int maximum, int style); + // create the label with given text and another one to show the time nearby // as the next windows in the sizer, returns the created control wxStaticText *CreateLabel(const wxString& text, wxSizer *sizer); @@ -101,25 +164,10 @@ private: wxStaticText *m_elapsed, *m_estimated, *m_remaining; - // time when the dialog was created - unsigned long m_timeStart; - // time when the dialog was closed or cancelled - unsigned long m_timeStop; - // time between the moment the dialog was closed/cancelled and resume - unsigned long m_break; // parent top level window (may be NULL) wxWindow *m_parentTop; - // continue processing or not (return value for Update()) - enum - { - Uncancelable = -1, // dialog can't be canceled - Canceled, // can be cancelled and, in fact, was - Continue, // can be cancelled but wasn't - Finished // finished, waiting to be removed from screen - } m_state; - // skip some portion bool m_skip; @@ -129,16 +177,15 @@ private: wxButton *m_btnSkip; #endif - // the maximum value - int m_maximum; - // saves the time when elapsed time was updated so there is only one // update per second unsigned long m_last_timeupdate; + // tells how often a change of the estimated time has to be confirmed - // before it is actually displayed - this reduces the frequence of updates + // before it is actually displayed - this reduces the frequency of updates // of estimated and remaining time - const int m_delay; + int m_delay; + // counts the confirmations int m_ctdelay; unsigned long m_display_estimated; @@ -146,20 +193,11 @@ private: bool m_hasAbortButton, m_hasSkipButton; -#if defined(__WXMSW__ ) || defined(__WXPM__) - // the factor we use to always keep the value in 16 bit range as the native - // control only supports ranges from 0 to 65,535 - size_t m_factor; -#endif // __WXMSW__ - // for wxPD_APP_MODAL case class WXDLLIMPEXP_FWD_CORE wxWindowDisabler *m_winDisabler; DECLARE_EVENT_TABLE() - DECLARE_DYNAMIC_CLASS(wxProgressDialog) - wxDECLARE_NO_COPY_CLASS(wxProgressDialog); + wxDECLARE_NO_COPY_CLASS(wxGenericProgressDialog); }; -#endif // wxUSE_PROGRESSDLG - #endif // __PROGDLGH_G__ diff --git a/include/wx/msw/progdlg.h b/include/wx/msw/progdlg.h new file mode 100644 index 0000000000..cd576dc8e9 --- /dev/null +++ b/include/wx/msw/progdlg.h @@ -0,0 +1,76 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/msw/progdlg.h +// Purpose: wxProgressDialog +// Author: Rickard Westerlund +// Created: 2010-07-22 +// RCS-ID: $Id$ +// Copyright: (c) 2010 wxWidgets team +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_PROGDLG_H_ +#define _WX_PROGDLG_H_ + +class wxProgressDialogTaskRunner; +class wxProgressDialogSharedData; + +class WXDLLIMPEXP_CORE wxProgressDialog : public wxGenericProgressDialog +{ +public: + wxProgressDialog(const wxString& title, const wxString& message, + int maximum = 100, + wxWindow *parent = NULL, + int style = wxPD_APP_MODAL | wxPD_AUTO_HIDE); + + virtual ~wxProgressDialog(); + + virtual bool Update(int value, const wxString& newmsg = wxEmptyString, bool *skip = NULL); + virtual bool Pulse(const wxString& newmsg = wxEmptyString, bool *skip = NULL); + + void Resume(); + + int GetValue() const; + wxString GetMessage() const; + + void SetRange(int maximum); + + // Return whether "Cancel" or "Skip" button was pressed, always return + // false if the corresponding button is not shown. + bool WasSkipped() const; + bool WasCancelled() const; + + virtual void SetTitle(const wxString& title); + virtual wxString GetTitle() const; + + virtual bool Show( bool show = true ); + + // Must provide overload to avoid hiding it (and warnings about it) + virtual void Update() { wxGenericProgressDialog::Update(); } + +private: + // Returns true if the task dialog is available. If not, all the methods of + // this class simply fall back to wxGenericProgressDialog versions. + bool HasNativeProgressDialog() const; + + // Performs common routines to Update() and Pulse(). Requires the + // shared object to have been entered. + bool DoNativeBeforeUpdate(bool *skip); + + // Updates the various timing informations for both determinate + // and indeterminate modes. Requires the shared object to have + // been entered. + void UpdateExpandedInformation(int value); + + wxProgressDialogTaskRunner *m_taskDialogRunner; + + wxProgressDialogSharedData *m_sharedData; + + // Store the message and title we currently use to be able to return it + // from Get{Message,Title}() + wxString m_message, + m_title; + + wxDECLARE_DYNAMIC_CLASS_NO_COPY(wxProgressDialog); +}; + +#endif // _WX_PROGDLG_H_ diff --git a/include/wx/progdlg.h b/include/wx/progdlg.h index dbce6e7275..48c708af02 100644 --- a/include/wx/progdlg.h +++ b/include/wx/progdlg.h @@ -14,6 +14,8 @@ #include "wx/defs.h" +#if wxUSE_PROGRESSDLG + /* * wxProgressDialog flags */ @@ -31,6 +33,28 @@ #include "wx/palmos/progdlg.h" #else #include "wx/generic/progdlgg.h" -#endif + + #if defined(__WXMSW__) && wxUSE_THREADS + #include "wx/msw/progdlg.h" + #else + class WXDLLIMPEXP_CORE wxProgressDialog + : public wxGenericProgressDialog + { + public: + wxProgressDialog( const wxString& title, const wxString& message, + int maximum = 100, + wxWindow *parent = NULL, + int style = wxPD_APP_MODAL | wxPD_AUTO_HIDE ) + : wxGenericProgressDialog( title, message, maximum, + parent, style ) + { } + + private: + wxDECLARE_DYNAMIC_CLASS_NO_COPY( wxProgressDialog ); + }; + #endif // defined(__WXMSW__) && wxUSE_THREADS +#endif // __WXPALMOS__ + +#endif // wxUSE_PROGRESSDLG #endif // _WX_PROGDLG_H_BASE_ diff --git a/samples/dialogs/dialogs.cpp b/samples/dialogs/dialogs.cpp index 2a0a1b95e2..3abb136139 100644 --- a/samples/dialogs/dialogs.cpp +++ b/samples/dialogs/dialogs.cpp @@ -1756,25 +1756,26 @@ void MyFrame::ShowProgress( wxCommandEvent& WXUNUSED(event) ) { static const int max = 100; - wxProgressDialog dialog(wxT("Progress dialog example"), - wxT("An informative message"), + wxProgressDialog dialog("Progress dialog example", + // "Reserve" enough space for the multiline + // messages below, we'll change it anyhow + // immediately in the loop below + wxString(' ', 100) + "\n\n\n\n", max, // range this, // parent wxPD_CAN_ABORT | wxPD_CAN_SKIP | wxPD_APP_MODAL | - // wxPD_AUTO_HIDE | -- try this as well + //wxPD_AUTO_HIDE | // -- try this as well wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME | - wxPD_REMAINING_TIME - | wxPD_SMOOTH // - makes indeterminate mode bar on WinXP very small + wxPD_REMAINING_TIME | + wxPD_SMOOTH // - makes indeterminate mode bar on WinXP very small ); bool cont = true; for ( int i = 0; i <= max; i++ ) { - wxMilliSleep(200); - wxString msg; // test both modes of wxProgressDialog behaviour: start in @@ -1783,15 +1784,25 @@ void MyFrame::ShowProgress( wxCommandEvent& WXUNUSED(event) ) if ( i == max ) { - msg = wxT("That's all, folks!"); + msg = "That's all, folks!\n" + "\n" + "Nothing to see here any more."; } else if ( !determinate ) { - msg = wxT("Testing indeterminate mode"); + msg = "Testing indeterminate mode\n" + "\n" + "This mode allows you to show to the user\n" + "that something is going on even if you don't know\n" + "when exactly will you finish."; } else if ( determinate ) { - msg = wxT("Now in standard determinate mode"); + msg = "Now in standard determinate mode\n" + "\n" + "This is the standard usage mode in which you\n" + "update the dialog after performing each new step of work.\n" + "It requires knowing the total number of steps in advance."; } // will be set to true if "Skip" button was pressed @@ -1807,8 +1818,13 @@ void MyFrame::ShowProgress( wxCommandEvent& WXUNUSED(event) ) // each skip will move progress about quarter forward if ( skip ) + { i += max/4; + if ( i >= 100 ) + i = 99; + } + if ( !cont ) { if ( wxMessageBox(wxT("Do you really want to cancel?"), @@ -1819,6 +1835,8 @@ void MyFrame::ShowProgress( wxCommandEvent& WXUNUSED(event) ) cont = true; dialog.Resume(); } + + wxMilliSleep(200); } if ( !cont ) diff --git a/src/generic/printps.cpp b/src/generic/printps.cpp index c23f21a9f8..855b65a7a6 100644 --- a/src/generic/printps.cpp +++ b/src/generic/printps.cpp @@ -40,7 +40,7 @@ #include "wx/generic/printps.h" #include "wx/printdlg.h" #include "wx/generic/prntdlgg.h" -#include "wx/generic/progdlgg.h" +#include "wx/progdlg.h" #include "wx/paper.h" #include diff --git a/src/generic/progdlgg.cpp b/src/generic/progdlgg.cpp index 7e0e373f09..9cb3d3451f 100644 --- a/src/generic/progdlgg.cpp +++ b/src/generic/progdlgg.cpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // Name: src/generic/progdlgg.cpp -// Purpose: wxProgressDialog class +// Purpose: wxGenericProgressDialog class // Author: Karsten Ballueder // Modified by: // Created: 09.05.1999 @@ -66,49 +66,98 @@ static const int wxID_SKIP = 32000; // whatever -// ---------------------------------------------------------------------------- -// private functions -// ---------------------------------------------------------------------------- - -// update the label to show the given time (in seconds) -static void SetTimeLabel(unsigned long val, wxStaticText *label); - // ---------------------------------------------------------------------------- // event tables // ---------------------------------------------------------------------------- -BEGIN_EVENT_TABLE(wxProgressDialog, wxDialog) - EVT_BUTTON(wxID_CANCEL, wxProgressDialog::OnCancel) - EVT_BUTTON(wxID_SKIP, wxProgressDialog::OnSkip) +BEGIN_EVENT_TABLE(wxGenericProgressDialog, wxDialog) + EVT_BUTTON(wxID_CANCEL, wxGenericProgressDialog::OnCancel) + EVT_BUTTON(wxID_SKIP, wxGenericProgressDialog::OnSkip) - EVT_CLOSE(wxProgressDialog::OnClose) + EVT_CLOSE(wxGenericProgressDialog::OnClose) END_EVENT_TABLE() -IMPLEMENT_CLASS(wxProgressDialog, wxDialog) - // ============================================================================ -// wxProgressDialog implementation +// wxGenericProgressDialog implementation // ============================================================================ +wxIMPLEMENT_CLASS(wxProgressDialog, wxDialog) + // ---------------------------------------------------------------------------- -// wxProgressDialog creation +// wxGenericProgressDialog creation // ---------------------------------------------------------------------------- -wxProgressDialog::wxProgressDialog(const wxString& title, - const wxString& message, - int maximum, - wxWindow *parent, - int style) - : wxDialog(GetParentForModalDialog(parent, style), wxID_ANY, title), - m_skip(false), - m_delay(3), - m_hasAbortButton(false), - m_hasSkipButton(false) +void wxGenericProgressDialog::Init(wxWindow *parent, int maximum, int style) { + // Initialize the inherited members that we always use (even when we don't + // create a valid window here). + // we may disappear at any moment, let the others know about it SetExtraStyle(GetExtraStyle() | wxWS_EX_TRANSIENT); m_windowStyle |= style; + m_parentTop = wxGetTopLevelParent(parent); + + + // Initialize our own members. + m_state = Uncancelable; + m_maximum = maximum; + +#if defined(__WXMSW__) || defined(__WXPM__) + // we can't have values > 65,536 in the progress control under Windows, so + // scale everything down + m_factor = m_maximum / 65536 + 1; + m_maximum /= m_factor; +#endif // __WXMSW__ + + + m_timeStart = wxGetCurrentTime(); + m_timeStop = (unsigned long)-1; + m_break = 0; + + m_skip = false; + + m_display_estimated = + m_last_timeupdate = + m_ctdelay = 0; + + m_delay = 3; + + m_hasAbortButton = + m_hasSkipButton = false; +} + +wxGenericProgressDialog::wxGenericProgressDialog(wxWindow *parent, + int maximum, + int style) + : wxDialog() +{ + Init(parent, maximum, style); +} + +wxGenericProgressDialog::wxGenericProgressDialog(const wxString& title, + const wxString& message, + int maximum, + wxWindow *parent, + int style) + : wxDialog() +{ + Init(parent, maximum, style); + + Create( title, message, maximum, parent, style ); +} + +void wxGenericProgressDialog::Create( const wxString& title, + const wxString& message, + int maximum, + wxWindow *parent, + int style ) +{ + wxDialog::Create(GetParentForModalDialog(parent, style), wxID_ANY, title); + + SetParent( GetParentForModalDialog(parent, style) ); + SetTitle( title ); + m_hasAbortButton = (style & wxPD_CAN_ABORT) != 0; m_hasSkipButton = (style & wxPD_CAN_SKIP) != 0; @@ -128,16 +177,6 @@ wxProgressDialog::wxProgressDialog(const wxString& title, #endif m_state = m_hasAbortButton ? Continue : Uncancelable; - m_maximum = maximum; - -#if defined(__WXMSW__) || defined(__WXPM__) - // we can't have values > 65,536 in the progress control under Windows, so - // scale everything down - m_factor = m_maximum / 65536 + 1; - m_maximum /= m_factor; -#endif // __WXMSW__ - - m_parentTop = wxGetTopLevelParent(parent); // top-level sizerTop wxSizer * const sizerTop = new wxBoxSizer(wxVERTICAL); @@ -173,10 +212,6 @@ wxProgressDialog::wxProgressDialog(const wxString& title, m_elapsed = m_estimated = m_remaining = NULL; - m_display_estimated = - m_last_timeupdate = - m_break = 0; - m_ctdelay = 0; // also count how many labels we really have size_t nTimeLabels = 0; @@ -187,30 +222,24 @@ wxProgressDialog::wxProgressDialog(const wxString& title, { nTimeLabels++; - m_elapsed = CreateLabel(_("Elapsed time:"), sizerLabels); + m_elapsed = CreateLabel(GetElapsedLabel(), sizerLabels); } if ( style & wxPD_ESTIMATED_TIME ) { nTimeLabels++; - m_estimated = CreateLabel(_("Estimated time:"), sizerLabels); + m_estimated = CreateLabel(GetEstimatedLabel(), sizerLabels); } if ( style & wxPD_REMAINING_TIME ) { nTimeLabels++; - m_remaining = CreateLabel(_("Remaining time:"), sizerLabels); + m_remaining = CreateLabel(GetRemainingLabel(), sizerLabels); } sizerTop->Add(sizerLabels, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP, LAYOUT_MARGIN); - if ( nTimeLabels > 0 ) - { - // set it to the current time - m_timeStart = wxGetCurrentTime(); - } - #if defined(__SMARTPHONE__) if ( m_hasSkipButton ) SetRightMenu(wxID_SKIP, _("Skip")); @@ -255,16 +284,7 @@ wxProgressDialog::wxProgressDialog(const wxString& title, Centre(wxCENTER_FRAME | wxBOTH); - if ( style & wxPD_APP_MODAL ) - { - m_winDisabler = new wxWindowDisabler(this); - } - else - { - if ( m_parentTop ) - m_parentTop->Disable(); - m_winDisabler = NULL; - } + DisableOtherWindows(); Show(); Enable(); @@ -280,8 +300,82 @@ wxProgressDialog::wxProgressDialog(const wxString& title, Update(); } +void wxGenericProgressDialog::UpdateTimeEstimates(int value, + unsigned long &elapsedTime, + unsigned long &estimatedTime, + unsigned long &remainingTime) +{ + unsigned long elapsed = wxGetCurrentTime() - m_timeStart; + if ( value != 0 && (m_last_timeupdate < elapsed || value == m_maximum) ) + { + m_last_timeupdate = elapsed; + unsigned long estimated = m_break + + (unsigned long)(( (double) (elapsed-m_break) * m_maximum ) / ((double)value)) ; + if ( estimated > m_display_estimated + && m_ctdelay >= 0 + ) + { + ++m_ctdelay; + } + else if ( estimated < m_display_estimated + && m_ctdelay <= 0 + ) + { + --m_ctdelay; + } + else + { + m_ctdelay = 0; + } + if ( m_ctdelay >= m_delay // enough confirmations for a higher value + || m_ctdelay <= (m_delay*-1) // enough confirmations for a lower value + || value == m_maximum // to stay consistent + || elapsed > m_display_estimated // to stay consistent + || ( elapsed > 0 && elapsed < 4 ) // additional updates in the beginning + ) + { + m_display_estimated = estimated; + m_ctdelay = 0; + } + } + + if ( value != 0 ) + { + long display_remaining = m_display_estimated - elapsed; + if ( display_remaining < 0 ) + { + display_remaining = 0; + } + + estimatedTime = m_display_estimated; + remainingTime = display_remaining; + } + + elapsedTime = elapsed; +} + +// static +wxString wxGenericProgressDialog::GetFormattedTime(unsigned long timeInSec) +{ + wxString timeAsHMS; + + if ( timeInSec == (unsigned long)-1 ) + { + timeAsHMS = _("Unknown"); + } + else + { + unsigned hours = timeInSec / 3600; + unsigned minutes = (timeInSec % 3600) / 60; + unsigned seconds = timeInSec % 60; + timeAsHMS.Printf("%u:%02u:%02u", hours, minutes, seconds); + } + + return timeAsHMS; +} + wxStaticText * -wxProgressDialog::CreateLabel(const wxString& text, wxSizer *sizer) +wxGenericProgressDialog::CreateLabel(const wxString& text, wxSizer *sizer) { wxStaticText *label = new wxStaticText(this, wxID_ANY, text); wxStaticText *value = new wxStaticText(this, wxID_ANY, _("unknown")); @@ -305,11 +399,11 @@ wxProgressDialog::CreateLabel(const wxString& text, wxSizer *sizer) } // ---------------------------------------------------------------------------- -// wxProgressDialog operations +// wxGenericProgressDialog operations // ---------------------------------------------------------------------------- bool -wxProgressDialog::Update(int value, const wxString& newmsg, bool *skip) +wxGenericProgressDialog::Update(int value, const wxString& newmsg, bool *skip) { if ( !DoBeforeUpdate(skip) ) return false; @@ -329,47 +423,13 @@ wxProgressDialog::Update(int value, const wxString& newmsg, bool *skip) if ( (m_elapsed || m_remaining || m_estimated) && (value != 0) ) { - unsigned long elapsed = wxGetCurrentTime() - m_timeStart; - if ( m_last_timeupdate < elapsed - || value == m_maximum - ) - { - m_last_timeupdate = elapsed; - unsigned long estimated = m_break + - (unsigned long)(( (double) (elapsed-m_break) * m_maximum ) / ((double)value)) ; - if ( estimated > m_display_estimated - && m_ctdelay >= 0 - ) - { - ++m_ctdelay; - } - else if ( estimated < m_display_estimated - && m_ctdelay <= 0 - ) - { - --m_ctdelay; - } - else - { - m_ctdelay = 0; - } - if ( m_ctdelay >= m_delay // enough confirmations for a higher value - || m_ctdelay <= (m_delay*-1) // enough confirmations for a lower value - || value == m_maximum // to stay consistent - || elapsed > m_display_estimated // to stay consistent - || ( elapsed > 0 && elapsed < 4 ) // additional updates in the beginning - ) - { - m_display_estimated = estimated; - m_ctdelay = 0; - } - } + unsigned long elapsed; + unsigned long display_remaining; - long display_remaining = m_display_estimated - elapsed; - if ( display_remaining < 0 ) - { - display_remaining = 0; - } + UpdateTimeEstimates( value, + elapsed, + m_display_estimated, + display_remaining ); SetTimeLabel(elapsed, m_elapsed); SetTimeLabel(m_display_estimated, m_estimated); @@ -405,7 +465,7 @@ wxProgressDialog::Update(int value, const wxString& newmsg, bool *skip) } wxCHECK_MSG(wxEventLoopBase::GetActive(), false, - "wxProgressDialog::Update needs a running event loop"); + "wxGenericProgressDialog::Update needs a running event loop"); // allow the window to repaint: // NOTE: since we yield only for UI events with this call, there @@ -438,7 +498,7 @@ wxProgressDialog::Update(int value, const wxString& newmsg, bool *skip) return m_state != Canceled; } -bool wxProgressDialog::Pulse(const wxString& newmsg, bool *skip) +bool wxGenericProgressDialog::Pulse(const wxString& newmsg, bool *skip) { if ( !DoBeforeUpdate(skip) ) return false; @@ -464,10 +524,10 @@ bool wxProgressDialog::Pulse(const wxString& newmsg, bool *skip) return m_state != Canceled; } -bool wxProgressDialog::DoBeforeUpdate(bool *skip) +bool wxGenericProgressDialog::DoBeforeUpdate(bool *skip) { wxCHECK_MSG(wxEventLoopBase::GetActive(), false, - "wxProgressDialog::DoBeforeUpdate needs a running event loop"); + "wxGenericProgressDialog::DoBeforeUpdate needs a running event loop"); // we have to yield because not only we want to update the display but // also to process the clicks on the cancel and skip buttons @@ -487,10 +547,10 @@ bool wxProgressDialog::DoBeforeUpdate(bool *skip) return m_state != Canceled; } -void wxProgressDialog::DoAfterUpdate() +void wxGenericProgressDialog::DoAfterUpdate() { wxCHECK_RET(wxEventLoopBase::GetActive(), - "wxProgressDialog::DoAfterUpdate needs a running event loop"); + "wxGenericProgressDialog::DoAfterUpdate needs a running event loop"); // allow the window to repaint: // NOTE: since we yield only for UI events with this call, there @@ -498,7 +558,7 @@ void wxProgressDialog::DoAfterUpdate() wxEventLoopBase::GetActive()->YieldFor(wxEVT_CATEGORY_UI); } -void wxProgressDialog::Resume() +void wxGenericProgressDialog::Resume() { m_state = Continue; m_ctdelay = m_delay; // force an update of the elapsed/estimated/remaining time @@ -509,7 +569,7 @@ void wxProgressDialog::Resume() m_skip = false; } -bool wxProgressDialog::Show( bool show ) +bool wxGenericProgressDialog::Show( bool show ) { // reenable other windows before hiding this one because otherwise // Windows wouldn't give the focus back to the window which had @@ -520,26 +580,26 @@ bool wxProgressDialog::Show( bool show ) return wxDialog::Show(show); } -int wxProgressDialog::GetValue() const +int wxGenericProgressDialog::GetValue() const { if (m_gauge) return m_gauge->GetValue(); return wxNOT_FOUND; } -int wxProgressDialog::GetRange() const +int wxGenericProgressDialog::GetRange() const { if (m_gauge) return m_gauge->GetRange(); return wxNOT_FOUND; } -wxString wxProgressDialog::GetMessage() const +wxString wxGenericProgressDialog::GetMessage() const { return m_msg->GetLabel(); } -void wxProgressDialog::SetRange(int maximum) +void wxGenericProgressDialog::SetRange(int maximum) { wxASSERT_MSG(m_gauge, "The dialog should have been constructed with a range > 0"); wxASSERT_MSG(maximum > 0, "Invalid range"); @@ -556,22 +616,43 @@ void wxProgressDialog::SetRange(int maximum) } -bool wxProgressDialog::WasCancelled() const +bool wxGenericProgressDialog::WasCancelled() const { return m_hasAbortButton && m_state == Canceled; } -bool wxProgressDialog::WasSkipped() const +bool wxGenericProgressDialog::WasSkipped() const { return m_hasSkipButton && m_skip; } +// static +void wxGenericProgressDialog::SetTimeLabel(unsigned long val, + wxStaticText *label) +{ + if ( label ) + { + wxString s; + + if (val != (unsigned long)-1) + { + s = GetFormattedTime(val); + } + else + { + s = _("Unknown"); + } + + if ( s != label->GetLabel() ) + label->SetLabel(s); + } +} // ---------------------------------------------------------------------------- // event handlers // ---------------------------------------------------------------------------- -void wxProgressDialog::OnCancel(wxCommandEvent& event) +void wxGenericProgressDialog::OnCancel(wxCommandEvent& event) { if ( m_state == Finished ) { @@ -595,13 +676,13 @@ void wxProgressDialog::OnCancel(wxCommandEvent& event) } } -void wxProgressDialog::OnSkip(wxCommandEvent& WXUNUSED(event)) +void wxGenericProgressDialog::OnSkip(wxCommandEvent& WXUNUSED(event)) { DisableSkip(); m_skip = true; } -void wxProgressDialog::OnClose(wxCloseEvent& event) +void wxGenericProgressDialog::OnClose(wxCloseEvent& event) { if ( m_state == Uncancelable ) { @@ -628,13 +709,27 @@ void wxProgressDialog::OnClose(wxCloseEvent& event) // destruction // ---------------------------------------------------------------------------- -wxProgressDialog::~wxProgressDialog() +wxGenericProgressDialog::~wxGenericProgressDialog() { // normally this should have been already done, but just in case ReenableOtherWindows(); } -void wxProgressDialog::ReenableOtherWindows() +void wxGenericProgressDialog::DisableOtherWindows() +{ + if ( HasFlag(wxPD_APP_MODAL) ) + { + m_winDisabler = new wxWindowDisabler(this); + } + else + { + if ( m_parentTop ) + m_parentTop->Disable(); + m_winDisabler = NULL; + } +} + +void wxGenericProgressDialog::ReenableOtherWindows() { if ( HasFlag(wxPD_APP_MODAL) ) { @@ -651,30 +746,7 @@ void wxProgressDialog::ReenableOtherWindows() // private functions // ---------------------------------------------------------------------------- -static void SetTimeLabel(unsigned long val, wxStaticText *label) -{ - if ( label ) - { - wxString s; - - if (val != (unsigned long)-1) - { - unsigned long hours = val / 3600; - unsigned long minutes = (val % 3600) / 60; - unsigned long seconds = val % 60; - s.Printf(wxT("%lu:%02lu:%02lu"), hours, minutes, seconds); - } - else - { - s = _("Unknown"); - } - - if ( s != label->GetLabel() ) - label->SetLabel(s); - } -} - -void wxProgressDialog::EnableSkip(bool enable) +void wxGenericProgressDialog::EnableSkip(bool enable) { if(m_hasSkipButton) { @@ -690,7 +762,7 @@ void wxProgressDialog::EnableSkip(bool enable) } } -void wxProgressDialog::EnableAbort(bool enable) +void wxGenericProgressDialog::EnableAbort(bool enable) { if(m_hasAbortButton) { @@ -706,7 +778,7 @@ void wxProgressDialog::EnableAbort(bool enable) } } -void wxProgressDialog::EnableClose() +void wxGenericProgressDialog::EnableClose() { if(m_hasAbortButton) { @@ -722,10 +794,10 @@ void wxProgressDialog::EnableClose() } } -void wxProgressDialog::UpdateMessage(const wxString &newmsg) +void wxGenericProgressDialog::UpdateMessage(const wxString &newmsg) { wxCHECK_RET(wxEventLoopBase::GetActive(), - "wxProgressDialog::UpdateMessage needs a running event loop"); + "wxGenericProgressDialog::UpdateMessage needs a running event loop"); if ( !newmsg.empty() && newmsg != m_msg->GetLabel() ) { diff --git a/src/msw/progdlg.cpp b/src/msw/progdlg.cpp new file mode 100644 index 0000000000..b86f98986b --- /dev/null +++ b/src/msw/progdlg.cpp @@ -0,0 +1,881 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: src/msw/progdlg.cpp +// Purpose: wxProgressDialog +// Author: Rickard Westerlund +// Created: 2010-07-22 +// RCS-ID: $Id$ +// Copyright: (c) 2010 wxWidgets team +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// Declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// Headers +// ---------------------------------------------------------------------------- + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#if wxUSE_PROGRESSDLG && wxUSE_THREADS + +#include "wx/msw/private/msgdlg.h" +#include "wx/progdlg.h" + +using namespace wxMSWMessageDialog; + +#ifdef wxHAS_MSW_TASKDIALOG + +// ---------------------------------------------------------------------------- +// Constants +// ---------------------------------------------------------------------------- + +namespace +{ + +// Notification values of wxProgressDialogSharedData::m_notifications +const int wxSPDD_VALUE_CHANGED = 0x0001; +const int wxSPDD_RANGE_CHANGED = 0x0002; +const int wxSPDD_PBMARQUEE_CHANGED = 0x0004; +const int wxSPDD_TITLE_CHANGED = 0x0008; +const int wxSPDD_MESSAGE_CHANGED = 0x0010; +const int wxSPDD_EXPINFO_CHANGED = 0x0020; +const int wxSPDD_ENABLE_SKIP = 0x0040; +const int wxSPDD_ENABLE_ABORT = 0x0080; +const int wxSPDD_DISABLE_SKIP = 0x0100; +const int wxSPDD_DISABLE_ABORT = 0x0200; +const int wxSPDD_FINISHED = 0x0400; +const int wxSPDD_DESTROYED = 0x0800; + +const int Id_SkipBtn = wxID_HIGHEST + 1; + +} // anonymous namespace + +// ============================================================================ +// Helper classes +// ============================================================================ + +// Class used to share data between the main thread and the task dialog runner. +class wxProgressDialogSharedData +{ +public: + wxProgressDialogSharedData() + { + m_hwnd = 0; + m_value = 0; + m_progressBarMarquee = false; + m_skipped = false; + m_notifications = 0; + } + + wxCriticalSection m_cs; + + HWND m_hwnd; // Task dialog handler + long m_style; // wxProgressDialog style + int m_value; + int m_range; + wxString m_title; + wxString m_message; + wxString m_expandedInformation; + wxString m_labelCancel; // Privately used by callback. + unsigned long m_timeStop; + + wxGenericProgressDialog::ProgressDialogState m_state; + bool m_progressBarMarquee; + bool m_skipped; + + // Bit field that indicates fields that have been modified by the + // main thread so the task dialog runner knows what to update. + int m_notifications; +}; + +// Runner thread that takes care of displaying and updating the +// task dialog. +class wxProgressDialogTaskRunner : public wxThread +{ +public: + wxProgressDialogTaskRunner(wxWindow* parent) + : wxThread(wxTHREAD_JOINABLE), + m_parent(parent) + { } + + wxProgressDialogSharedData* GetSharedDataObject() + { return &m_sharedData; } + +private: + wxWindow* m_parent; + wxProgressDialogSharedData m_sharedData; + + virtual void* Entry(); + + static HRESULT CALLBACK TaskDialogCallbackProc(HWND hwnd, + UINT uNotification, + WPARAM wParam, + LPARAM lParam, + LONG_PTR dwRefData); +}; + +// ============================================================================ +// Helper functions +// ============================================================================ + +namespace +{ + +bool UsesCloseButtonOnly(long style) +{ + return !((style & wxPD_CAN_ABORT) || (style & wxPD_AUTO_HIDE)); +} + +BOOL CALLBACK DisplayCloseButton(HWND hwnd, LPARAM lParam) +{ + wxProgressDialogSharedData *sharedData = + (wxProgressDialogSharedData *) lParam; + + if ( wxGetWindowText( hwnd ) == sharedData->m_labelCancel ) + { + sharedData->m_labelCancel = _("Close"); + SendMessage( hwnd, WM_SETTEXT, 0, + (LPARAM) sharedData->m_labelCancel.wx_str() ); + + return FALSE; + } + + return TRUE; +} + +void PerformNotificationUpdates(HWND hwnd, + wxProgressDialogSharedData *sharedData) +{ + // Update the appropriate dialog fields. + if ( sharedData->m_notifications & wxSPDD_RANGE_CHANGED ) + { + ::SendMessage( hwnd, + TDM_SET_PROGRESS_BAR_RANGE, + 0, + MAKELPARAM(0, sharedData->m_range) ); + } + + if ( sharedData->m_notifications & wxSPDD_VALUE_CHANGED ) + { + ::SendMessage( hwnd, + TDM_SET_PROGRESS_BAR_POS, + sharedData->m_value, + 0 ); + } + + if ( sharedData->m_notifications & wxSPDD_PBMARQUEE_CHANGED ) + { + BOOL val = sharedData->m_progressBarMarquee ? TRUE : FALSE; + ::SendMessage( hwnd, + TDM_SET_MARQUEE_PROGRESS_BAR, + val, + 0 ); + ::SendMessage( hwnd, + TDM_SET_PROGRESS_BAR_MARQUEE, + val, + 0 ); + } + + if ( sharedData->m_notifications & wxSPDD_TITLE_CHANGED ) + ::SetWindowText( hwnd, sharedData->m_title.wx_str() ); + + if ( sharedData->m_notifications & wxSPDD_MESSAGE_CHANGED ) + { + // Split the message in the title string and the rest if it has + // multiple lines. + wxString + title = sharedData->m_message, + body; + + const size_t posNL = title.find('\n'); + if ( posNL != wxString::npos ) + { + // There can an extra new line between the first and subsequent + // lines to separate them as it looks better with the generic + // version -- but in this one, they're already separated by the use + // of different dialog elements, so suppress the extra new line. + int numNLs = 1; + if ( posNL < title.length() - 1 && title[posNL + 1] == '\n' ) + numNLs++; + + body.assign(title, posNL + numNLs, wxString::npos); + title.erase(posNL); + } + + ::SendMessage( hwnd, + TDM_SET_ELEMENT_TEXT, + TDE_MAIN_INSTRUCTION, + (LPARAM) title.wx_str() ); + + ::SendMessage( hwnd, + TDM_SET_ELEMENT_TEXT, + TDE_CONTENT, + (LPARAM) body.wx_str() ); + } + + if ( sharedData->m_notifications & wxSPDD_EXPINFO_CHANGED ) + { + const wxString& expandedInformation = + sharedData->m_expandedInformation; + if ( !expandedInformation.empty() ) + { + ::SendMessage( hwnd, + TDM_SET_ELEMENT_TEXT, + TDE_EXPANDED_INFORMATION, + (LPARAM) expandedInformation.wx_str() ); + } + } + + if ( sharedData->m_notifications & wxSPDD_ENABLE_SKIP ) + ::SendMessage( hwnd, TDM_ENABLE_BUTTON, Id_SkipBtn, TRUE ); + + if ( sharedData->m_notifications & wxSPDD_ENABLE_ABORT ) + ::SendMessage( hwnd, TDM_ENABLE_BUTTON, IDCANCEL, TRUE ); + + if ( sharedData->m_notifications & wxSPDD_DISABLE_SKIP ) + ::SendMessage( hwnd, TDM_ENABLE_BUTTON, Id_SkipBtn, FALSE ); + + if ( sharedData->m_notifications & wxSPDD_DISABLE_ABORT ) + ::SendMessage( hwnd, TDM_ENABLE_BUTTON, IDCANCEL, FALSE ); + + // Is the progress finished? + if ( sharedData->m_notifications & wxSPDD_FINISHED ) + { + sharedData->m_state = wxGenericProgressDialog::Finished; + + if ( !(sharedData->m_style & wxPD_AUTO_HIDE) ) + { + // Change Cancel into Close and activate the button. + ::SendMessage( hwnd, TDM_ENABLE_BUTTON, Id_SkipBtn, FALSE ); + ::SendMessage( hwnd, TDM_ENABLE_BUTTON, IDCANCEL, TRUE ); + ::EnumChildWindows( hwnd, DisplayCloseButton, + (LPARAM) sharedData ); + } + } +} + +} // anonymous namespace + +#endif // wxHAS_MSW_TASKDIALOG + +// ============================================================================ +// wxProgressDialog implementation +// ============================================================================ + +wxProgressDialog::wxProgressDialog( const wxString& title, + const wxString& message, + int maximum, + wxWindow *parent, + int style ) + : wxGenericProgressDialog(parent, maximum, style), + m_taskDialogRunner(NULL), + m_sharedData(NULL), + m_message(message), + m_title(title) +{ +#ifdef wxHAS_MSW_TASKDIALOG + if ( HasNativeProgressDialog() ) + { + Show(); + DisableOtherWindows(); + + return; + } +#endif // wxHAS_MSW_TASKDIALOG + + Create(title, message, maximum, parent, style); +} + +wxProgressDialog::~wxProgressDialog() +{ +#ifdef wxHAS_MSW_TASKDIALOG + if ( !m_taskDialogRunner ) + return; + + if ( m_sharedData ) + { + wxCriticalSectionLocker locker(m_sharedData->m_cs); + m_sharedData->m_notifications |= wxSPDD_DESTROYED; + } + + m_taskDialogRunner->Wait(); + + delete m_taskDialogRunner; + + ReenableOtherWindows(); + + if ( GetTopParent() ) + GetTopParent()->Raise(); +#endif // wxHAS_MSW_TASKDIALOG +} + +bool wxProgressDialog::Update(int value, const wxString& newmsg, bool *skip) +{ +#ifdef wxHAS_MSW_TASKDIALOG + if ( HasNativeProgressDialog() ) + { + wxCriticalSectionLocker locker(m_sharedData->m_cs); + + // Do nothing in canceled state. + if ( !DoNativeBeforeUpdate(skip) ) + return false; + + value /= m_factor; + + wxASSERT_MSG( value <= m_maximum, wxT("invalid progress value") ); + + m_sharedData->m_value = value; + m_sharedData->m_notifications |= wxSPDD_VALUE_CHANGED; + + if ( !newmsg.empty() ) + { + m_message = newmsg; + m_sharedData->m_message = newmsg; + m_sharedData->m_notifications |= wxSPDD_MESSAGE_CHANGED; + } + + if ( m_sharedData->m_progressBarMarquee ) + { + m_sharedData->m_progressBarMarquee = false; + m_sharedData->m_notifications |= wxSPDD_PBMARQUEE_CHANGED; + } + + UpdateExpandedInformation( value ); + + // Has the progress bar finished? + if ( value == m_maximum ) + { + if ( m_state == Finished ) + return true; + + m_state = Finished; + m_sharedData->m_state = Finished; + m_sharedData->m_notifications |= wxSPDD_FINISHED; + if( !HasFlag(wxPD_AUTO_HIDE) && newmsg.empty() ) + { + // Provide the finishing message if the application didn't. + m_message = _("Done."); + m_sharedData->m_message = m_message; + m_sharedData->m_notifications |= wxSPDD_MESSAGE_CHANGED; + } + } + + return m_sharedData->m_state != Canceled; + } +#endif // wxHAS_MSW_TASKDIALOG + + return wxGenericProgressDialog::Update( value, newmsg, skip ); +} + +bool wxProgressDialog::Pulse(const wxString& newmsg, bool *skip) +{ +#ifdef wxHAS_MSW_TASKDIALOG + if ( HasNativeProgressDialog() ) + { + wxCriticalSectionLocker locker(m_sharedData->m_cs); + + // Do nothing in canceled state. + if ( !DoNativeBeforeUpdate(skip) ) + return false; + + if ( !m_sharedData->m_progressBarMarquee ) + { + m_sharedData->m_progressBarMarquee = true; + m_sharedData->m_notifications |= wxSPDD_PBMARQUEE_CHANGED; + } + + if ( !newmsg.empty() ) + { + m_message = newmsg; + m_sharedData->m_message = newmsg; + m_sharedData->m_notifications |= wxSPDD_MESSAGE_CHANGED; + } + + // The value passed here doesn't matter, only elapsed time makes sense + // in indeterminate mode anyhow. + UpdateExpandedInformation(0); + + return m_sharedData->m_state != Canceled; + } +#endif // wxHAS_MSW_TASKDIALOG + + return wxGenericProgressDialog::Pulse( newmsg, skip ); +} + +bool wxProgressDialog::DoNativeBeforeUpdate(bool *skip) +{ +#ifdef wxHAS_MSW_TASKDIALOG + if ( HasNativeProgressDialog() ) + { + if ( m_sharedData->m_skipped ) + { + if ( skip && !*skip ) + { + *skip = true; + m_sharedData->m_skipped = false; + m_sharedData->m_notifications |= wxSPDD_ENABLE_SKIP; + } + } + + if ( m_sharedData->m_state == Canceled ) + m_timeStop = m_sharedData->m_timeStop; + + return m_sharedData->m_state != Canceled; + } +#endif // wxHAS_MSW_TASKDIALOG + + wxUnusedVar(skip); + wxFAIL_MSG( "unreachable" ); + + return false; +} + +void wxProgressDialog::Resume() +{ + wxGenericProgressDialog::Resume(); + +#ifdef wxHAS_MSW_TASKDIALOG + if ( HasNativeProgressDialog() ) + { + HWND hwnd; + + { + wxCriticalSectionLocker locker(m_sharedData->m_cs); + m_sharedData->m_state = m_state; + + // "Skip" was disabled when "Cancel" had been clicked, so re-enable + // it now. + m_sharedData->m_notifications |= wxSPDD_ENABLE_SKIP; + + if ( !UsesCloseButtonOnly(m_windowStyle) ) + m_sharedData->m_notifications |= wxSPDD_ENABLE_ABORT; + + hwnd = m_sharedData->m_hwnd; + } // Unlock m_cs, we can't call any function operating on a dialog with + // it locked as it can result in a deadlock if the dialog callback is + // called by Windows. + + // After resuming we need to bring the window on top of the Z-order as + // it could be hidden by another window shown from the main thread, + // e.g. a confirmation dialog asking whether the user really wants to + // abort. + // + // Notice that this must be done from the main thread as it owns the + // currently active window and attempts to do this from the task dialog + // thread would simply fail. + ::BringWindowToTop(hwnd); + } +#endif // wxHAS_MSW_TASKDIALOG +} + +int wxProgressDialog::GetValue() const +{ +#ifdef wxHAS_MSW_TASKDIALOG + if ( HasNativeProgressDialog() ) + { + wxCriticalSectionLocker locker(m_sharedData->m_cs); + return m_sharedData->m_value; + } +#endif // wxHAS_MSW_TASKDIALOG + + return wxGenericProgressDialog::GetValue(); +} + +wxString wxProgressDialog::GetMessage() const +{ +#ifdef wxHAS_MSW_TASKDIALOG + if ( HasNativeProgressDialog() ) + return m_message; +#endif // wxHAS_MSW_TASKDIALOG + + return wxGenericProgressDialog::GetMessage(); +} + +void wxProgressDialog::SetRange(int maximum) +{ + wxGenericProgressDialog::SetRange( maximum ); + +#ifdef wxHAS_MSW_TASKDIALOG + if ( HasNativeProgressDialog() ) + { + wxCriticalSectionLocker locker(m_sharedData->m_cs); + + m_sharedData->m_range = maximum; + m_sharedData->m_notifications |= wxSPDD_RANGE_CHANGED; + } +#endif // wxHAS_MSW_TASKDIALOG +} + +bool wxProgressDialog::WasSkipped() const +{ +#ifdef wxHAS_MSW_TASKDIALOG + if ( HasNativeProgressDialog() ) + { + if ( !m_sharedData ) + { + // Couldn't be skipped before being shown. + return false; + } + + wxCriticalSectionLocker locker(m_sharedData->m_cs); + return m_sharedData->m_skipped; + } +#endif // wxHAS_MSW_TASKDIALOG + + return wxGenericProgressDialog::WasSkipped(); +} + +bool wxProgressDialog::WasCancelled() const +{ +#ifdef wxHAS_MSW_TASKDIALOG + if ( HasNativeProgressDialog() ) + { + wxCriticalSectionLocker locker(m_sharedData->m_cs); + return m_sharedData->m_state == Canceled; + } +#endif // wxHAS_MSW_TASKDIALOG + + return wxGenericProgressDialog::WasCancelled(); +} + +void wxProgressDialog::SetTitle(const wxString& title) +{ +#ifdef wxHAS_MSW_TASKDIALOG + if ( HasNativeProgressDialog() ) + { + m_title = title; + + if ( m_sharedData ) + { + wxCriticalSectionLocker locker(m_sharedData->m_cs); + m_sharedData->m_title = title; + m_sharedData->m_notifications = wxSPDD_TITLE_CHANGED; + } + } +#endif // wxHAS_MSW_TASKDIALOG + + return wxGenericProgressDialog::SetTitle(title); +} + +wxString wxProgressDialog::GetTitle() const +{ +#ifdef wxHAS_MSW_TASKDIALOG + if ( HasNativeProgressDialog() ) + return m_title; +#endif // wxHAS_MSW_TASKDIALOG + + return wxGenericProgressDialog::GetTitle(); +} + +bool wxProgressDialog::Show(bool show) +{ +#ifdef wxHAS_MSW_TASKDIALOG + if ( HasNativeProgressDialog() ) + { + // The dialog can't be hidden at all and showing it again after it had + // been shown before doesn't do anything. + if ( !show || m_taskDialogRunner ) + return false; + + // We're showing the dialog for the first time, create the thread that + // will manage it. + m_taskDialogRunner = new wxProgressDialogTaskRunner(GetParent()); + m_sharedData = m_taskDialogRunner->GetSharedDataObject(); + + // Initialize shared data. + m_sharedData->m_title = m_title; + m_sharedData->m_message = m_message; + m_sharedData->m_range = m_maximum; + m_sharedData->m_state = Uncancelable; + m_sharedData->m_style = m_windowStyle; + + if ( HasFlag(wxPD_CAN_ABORT) ) + { + m_sharedData->m_state = Continue; + m_sharedData->m_labelCancel = _("Cancel"); + } + else if ( !HasFlag(wxPD_AUTO_HIDE) ) + { + m_sharedData->m_labelCancel = _("Close"); + } + + if ( m_windowStyle & (wxPD_ELAPSED_TIME + | wxPD_ESTIMATED_TIME + | wxPD_REMAINING_TIME) ) + { + // Use a non-empty string just to have the collapsible pane shown. + m_sharedData->m_expandedInformation = " "; + } + + // Do launch the thread. + if ( m_taskDialogRunner->Create() != wxTHREAD_NO_ERROR ) + { + wxLogError( "Unable to create thread!" ); + return false; + } + + if ( m_taskDialogRunner->Run() != wxTHREAD_NO_ERROR ) + { + wxLogError( "Unable to start thread!" ); + return false; + } + + if ( !HasFlag(wxPD_APP_MODAL) ) + GetParent()->Disable(); + //else: otherwise all windows will be disabled by m_taskDialogRunner + + // Do not show the underlying dialog. + return false; + } +#endif // wxHAS_MSW_TASKDIALOG + + return wxGenericProgressDialog::Show( show ); +} + +bool wxProgressDialog::HasNativeProgressDialog() const +{ +#ifdef wxHAS_MSW_TASKDIALOG + // For a native implementation task dialogs are required, which + // also require at least one button to be present so the flags needs + // to be checked as well to see if this is the case. + return HasNativeTaskDialog() + && ((m_windowStyle & (wxPD_CAN_SKIP | wxPD_CAN_ABORT)) + || !(m_windowStyle & wxPD_AUTO_HIDE)); +#else // !wxHAS_MSW_TASKDIALOG + // This shouldn't be even called in !wxHAS_MSW_TASKDIALOG case but as we + // still must define the function as returning something, return false. + return false; +#endif // wxHAS_MSW_TASKDIALOG/!wxHAS_MSW_TASKDIALOG +} + +void wxProgressDialog::UpdateExpandedInformation(int value) +{ +#ifdef wxHAS_MSW_TASKDIALOG + unsigned long elapsedTime; + unsigned long estimatedTime; + unsigned long remainingTime; + UpdateTimeEstimates(value, elapsedTime, estimatedTime, remainingTime); + + int realEstimatedTime = estimatedTime, + realRemainingTime = remainingTime; + if ( m_sharedData->m_progressBarMarquee ) + { + // In indeterminate mode we don't have any estimation neither for the + // remaining nor for estimated time. + realEstimatedTime = + realRemainingTime = -1; + } + + wxString expandedInformation; + + // Calculate the three different timing values. + if ( m_windowStyle & wxPD_ELAPSED_TIME ) + { + expandedInformation << GetElapsedLabel() + << " " + << GetFormattedTime(elapsedTime); + } + + if ( m_windowStyle & wxPD_ESTIMATED_TIME ) + { + if ( !expandedInformation.empty() ) + expandedInformation += "\n"; + + expandedInformation << GetEstimatedLabel() + << " " + << GetFormattedTime(realEstimatedTime); + } + + if ( m_windowStyle & wxPD_REMAINING_TIME ) + { + if ( !expandedInformation.empty() ) + expandedInformation += "\n"; + + expandedInformation << GetRemainingLabel() + << " " + << GetFormattedTime(realRemainingTime); + } + + // Update with new timing information. + if ( expandedInformation != m_sharedData->m_expandedInformation ) + { + m_sharedData->m_expandedInformation = expandedInformation; + m_sharedData->m_notifications |= wxSPDD_EXPINFO_CHANGED; + } +#else // !wxHAS_MSW_TASKDIALOG + wxUnusedVar(value); +#endif // wxHAS_MSW_TASKDIALOG/!wxHAS_MSW_TASKDIALOG +} + +// ---------------------------------------------------------------------------- +// wxProgressDialogTaskRunner and related methods +// ---------------------------------------------------------------------------- + +#ifdef wxHAS_MSW_TASKDIALOG + +void* wxProgressDialogTaskRunner::Entry() +{ + WinStruct tdc; + wxMSWTaskDialogConfig wxTdc; + + { + wxCriticalSectionLocker locker(m_sharedData.m_cs); + + wxTdc.caption = m_sharedData.m_title.wx_str(); + wxTdc.message = m_sharedData.m_message.wx_str(); + + wxTdc.MSWCommonTaskDialogInit( tdc ); + tdc.pfCallback = TaskDialogCallbackProc; + tdc.lpCallbackData = (LONG_PTR) &m_sharedData; + + // Undo some of the effects of MSWCommonTaskDialogInit(). + tdc.dwFlags &= ~TDF_EXPAND_FOOTER_AREA; // Expand in content area. + tdc.dwCommonButtons = 0; // Don't use common buttons. + + wxTdc.useCustomLabels = true; + + if ( m_sharedData.m_style & wxPD_CAN_SKIP ) + wxTdc.AddTaskDialogButton( tdc, Id_SkipBtn, 0, _("Skip") ); + + // Use a Cancel button when requested or use a Close button when + // the dialog does not automatically hide. + if ( (m_sharedData.m_style & wxPD_CAN_ABORT) + || !(m_sharedData.m_style & wxPD_AUTO_HIDE) ) + { + wxTdc.AddTaskDialogButton( tdc, IDCANCEL, 0, + m_sharedData.m_labelCancel ); + } + + tdc.dwFlags |= TDF_CALLBACK_TIMER + | TDF_SHOW_PROGRESS_BAR + | TDF_SHOW_MARQUEE_PROGRESS_BAR; + + if ( !m_sharedData.m_expandedInformation.empty() ) + { + tdc.pszExpandedInformation = + m_sharedData.m_expandedInformation.wx_str(); + } + } + + TaskDialogIndirect_t taskDialogIndirect = GetTaskDialogIndirectFunc(); + if ( !taskDialogIndirect ) + return NULL; + + int msAns; + HRESULT hr = taskDialogIndirect(&tdc, &msAns, NULL, NULL); + if ( FAILED(hr) ) + wxLogApiError( "TaskDialogIndirect", hr ); + + return NULL; +} + +// static +HRESULT CALLBACK +wxProgressDialogTaskRunner::TaskDialogCallbackProc + ( + HWND hwnd, + UINT uNotification, + WPARAM wParam, + LPARAM WXUNUSED(lParam), + LONG_PTR dwRefData + ) +{ + wxProgressDialogSharedData * const sharedData = + (wxProgressDialogSharedData *) dwRefData; + + wxCriticalSectionLocker locker(sharedData->m_cs); + + switch ( uNotification ) + { + case TDN_CREATED: + // Store the HWND for the main thread use. + sharedData->m_hwnd = hwnd; + + // Set the maximum value and disable Close button. + ::SendMessage( hwnd, + TDM_SET_PROGRESS_BAR_RANGE, + 0, + MAKELPARAM(0, sharedData->m_range) ); + + if ( UsesCloseButtonOnly(sharedData->m_style) ) + ::SendMessage( hwnd, TDM_ENABLE_BUTTON, IDCANCEL, FALSE ); + break; + + case TDN_BUTTON_CLICKED: + switch ( wParam ) + { + case Id_SkipBtn: + ::SendMessage(hwnd, TDM_ENABLE_BUTTON, Id_SkipBtn, FALSE); + sharedData->m_skipped = true; + return TRUE; + + case IDCANCEL: + if ( sharedData->m_state + == wxGenericProgressDialog::Finished ) + { + return FALSE; + } + + // Close button on the window triggers an IDCANCEL press, + // don't allow it when it should only be possible to close + // a finished dialog. + if ( !UsesCloseButtonOnly(sharedData->m_style) ) + { + wxCHECK_MSG( sharedData->m_state == + wxGenericProgressDialog::Continue, + TRUE, + "Dialog not in a cancelable state!"); + + ::SendMessage(hwnd, TDM_ENABLE_BUTTON, Id_SkipBtn, FALSE); + ::SendMessage(hwnd, TDM_ENABLE_BUTTON, IDCANCEL, FALSE); + + sharedData->m_timeStop = wxGetCurrentTime(); + sharedData->m_state = wxGenericProgressDialog::Canceled; + } + + return TRUE; + } + break; + + case TDN_TIMER: + PerformNotificationUpdates(hwnd, sharedData); + + // End dialog in three different cases: + // 1. Progress finished and dialog should automatically hide. + // 2. The wxProgressDialog object was destructed and should + // automatically hide. + // 3. The dialog was canceled and wxProgressDialog object + // was destroyed. + bool isCanceled = + sharedData->m_state == wxGenericProgressDialog::Canceled; + bool isFinished = + sharedData->m_state == wxGenericProgressDialog::Finished; + bool wasDestroyed = + (sharedData->m_notifications & wxSPDD_DESTROYED) != 0; + bool shouldAutoHide = (sharedData->m_style & wxPD_AUTO_HIDE) != 0; + + if ( (shouldAutoHide && (isFinished || wasDestroyed)) + || (wasDestroyed && isCanceled) ) + { + ::EndDialog( hwnd, IDCLOSE ); + } + + sharedData->m_notifications = 0; + + return TRUE; + } + + // Return anything. + return 0; +} + +#endif // wxHAS_MSW_TASKDIALOG + +#endif // wxUSE_PROGRESSDLG && wxUSE_THREADS