mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2026-01-04 19:10:09 +01:00
1
.gitignore
vendored
1
.gitignore
vendored
@@ -17,6 +17,7 @@ mydbstub.py*
|
||||
/license
|
||||
/*.egg-info
|
||||
/REV.txt
|
||||
/.idea
|
||||
|
||||
/bin/sip-*
|
||||
/bin/waf-*
|
||||
|
||||
9
TODO.rst
9
TODO.rst
@@ -128,10 +128,11 @@ Other Dev Stuff
|
||||
* Add a _msw module that will contain classes and such that are only
|
||||
available in the Windows port:
|
||||
|
||||
* axbase (ActiveX.)
|
||||
* wxCHMHelpController
|
||||
* metafile
|
||||
* access
|
||||
* [done] axbase
|
||||
* [done] metafile
|
||||
* [] wxCHMHelpController
|
||||
* [] access
|
||||
* [] New activex classes in wx/msw/ole/activex.h ?
|
||||
* Any others?
|
||||
|
||||
* Add _propdlg module
|
||||
|
||||
@@ -66,7 +66,7 @@ class TestPanel(wx.Panel):
|
||||
btnSizer.Add(txt, 0, wx.CENTER|wx.ALL, 2)
|
||||
|
||||
self.location = wx.ComboBox(
|
||||
self, -1, "", style=wx.CB_DROPDOWN|wx.PROCESS_ENTER
|
||||
self, -1, "", style=wx.CB_DROPDOWN|wx.TE_PROCESS_ENTER
|
||||
)
|
||||
|
||||
self.Bind(wx.EVT_COMBOBOX, self.OnLocationSelect, self.location)
|
||||
|
||||
68
etg/_msw.py
Normal file
68
etg/_msw.py
Normal file
@@ -0,0 +1,68 @@
|
||||
# ---------------------------------------------------------------------------
|
||||
# Name: etg/_msw.py
|
||||
# Author: Dietmar Schwertberger
|
||||
#
|
||||
# Created: 13-Nov-2015
|
||||
# Copyright: (c) 2015-2016 by Total Control Software
|
||||
# License: wxWindows License
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_msw"
|
||||
NAME = "_msw" # Base name of the file to generate to for this script
|
||||
DOCSTRING = ""
|
||||
|
||||
# The classes and/or the basename of the Doxygen XML files to be processed by
|
||||
# this script.
|
||||
ITEMS = []
|
||||
|
||||
# The list of other ETG scripts and back-end generator modules that are
|
||||
# included as part of this module. These items are in their own etg scripts
|
||||
# for easier maintainability, but their class and function definitions are
|
||||
# intended to be part of this module, not their own module. This also makes it
|
||||
# easier to promote one of these to module status later if desired, simply
|
||||
# remove it from this list of Includes, and change the MODULE value in the
|
||||
# promoted script to be the same as its NAME.
|
||||
|
||||
INCLUDES = ['metafile',
|
||||
'axbase',
|
||||
]
|
||||
|
||||
# Separate the list into those that are generated from ETG scripts and the
|
||||
# rest. These lists can be used from the build scripts to get a list of
|
||||
# sources and/or additional dependencies when building this extension module.
|
||||
ETGFILES = ['etg/%s.py' % NAME] + tools.getEtgFiles(INCLUDES)
|
||||
DEPENDS = tools.getNonEtgFiles(INCLUDES)
|
||||
OTHERDEPS = []
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def run():
|
||||
# Parse the XML file(s) building a collection of Extractor objects
|
||||
module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
|
||||
etgtools.parseDoxyXML(module, ITEMS)
|
||||
module.check4unittest = False
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# Tweak the parsed meta objects in the module object as needed for
|
||||
# customizing the generated code and docstrings.
|
||||
|
||||
module.addHeaderCode('#include <wxpy_api.h>')
|
||||
module.addImport('_core')
|
||||
module.addPyCode('import wx', order=10)
|
||||
module.addInclude(INCLUDES)
|
||||
|
||||
# -----------------------------------------------------------------
|
||||
# -----------------------------------------------------------------
|
||||
tools.doCommonTweaks(module)
|
||||
tools.runGenerators(module)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
@@ -49,6 +49,14 @@ def run():
|
||||
# keep e.g. '(const wxString &fileName)'
|
||||
item.ignore()
|
||||
|
||||
# Transplant the docstrings from the ignored Load methods into the
|
||||
# appropriate compatibility method
|
||||
if 'proxy' in item.argsString:
|
||||
m = c.find('LoadURIWithProxy')
|
||||
else:
|
||||
m = c.find('LoadURI')
|
||||
m.briefDoc = item.briefDoc
|
||||
m.detailedDoc = item.detailedDoc
|
||||
|
||||
|
||||
c = module.find('wxMediaEvent')
|
||||
|
||||
52
etg/metafile.py
Normal file
52
etg/metafile.py
Normal file
@@ -0,0 +1,52 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# Name: etg/metafile.py
|
||||
# Author: Robin Dunn
|
||||
# Dietmar Schwertberger
|
||||
#
|
||||
# Created: 01-Nov-2015
|
||||
# Copyright: (c) 2015 by Wide Open Technologies
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_core"
|
||||
NAME = "metafile" # Base name of the file to generate to for this script
|
||||
DOCSTRING = ""
|
||||
|
||||
# The classes and/or the basename of the Doxygen XML files to be processed by
|
||||
# this script.
|
||||
ITEMS = [ 'wxMetafile',
|
||||
'wxMetafileDC',
|
||||
]
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
def run():
|
||||
# Parse the XML file(s) building a collection of Extractor objects
|
||||
module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
|
||||
etgtools.parseDoxyXML(module, ITEMS)
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
# Tweak the parsed meta objects in the module object as needed for
|
||||
# customizing the generated code and docstrings.
|
||||
|
||||
c = module.find('wxMetafile')
|
||||
c.addPrivateCopyCtor()
|
||||
|
||||
c = module.find('wxMetafileDC')
|
||||
c.addPrivateCopyCtor()
|
||||
|
||||
module.find("wxMakeMetafilePlaceable").ignore()
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.doCommonTweaks(module)
|
||||
tools.runGenerators(module)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
Submodule ext/wxWidgets updated: e44418ba2d...a36e071cd4
79
src/axbase.sip
Normal file
79
src/axbase.sip
Normal file
@@ -0,0 +1,79 @@
|
||||
//--------------------------------------------------------------------------
|
||||
// Name: src/axbase.sip
|
||||
// Purpose: A wxWindow class and wrapper interface that virtualizes
|
||||
// MSWTranslateMessage for use in ActiveX Controls. See _axbase in Classic
|
||||
//
|
||||
// Author: Robin Dunn
|
||||
//
|
||||
// Created: 13-May-2016
|
||||
// Copyright: (c) 2016 by Total Control Software
|
||||
// Licence: wxWindows license
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
%ModuleHeaderCode
|
||||
class wxPyAxBaseWindow : public wxWindow
|
||||
{
|
||||
DECLARE_DYNAMIC_CLASS(wxPyAxBaseWindow)
|
||||
|
||||
public:
|
||||
wxPyAxBaseWindow(wxWindow* parent, const wxWindowID id=-1,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = 0,
|
||||
const wxString& name = wxPanelNameStr)
|
||||
: wxWindow(parent, id, pos, size, style, name) {}
|
||||
|
||||
wxPyAxBaseWindow() : wxWindow() {}
|
||||
|
||||
virtual bool MSWTranslateMessage(WXMSG* msg)
|
||||
{
|
||||
return wxWindow::MSWTranslateMessage(msg);
|
||||
}
|
||||
};
|
||||
|
||||
wxPyAxBaseWindow* wxPyAxBaseWindow_FromHWND(wxWindow* parent, unsigned long _hWnd);
|
||||
%End
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
%ModuleCode
|
||||
IMPLEMENT_DYNAMIC_CLASS(wxPyAxBaseWindow, wxWindow);
|
||||
|
||||
wxPyAxBaseWindow* wxPyAxBaseWindow_FromHWND(wxWindow* parent, unsigned long _hWnd)
|
||||
{
|
||||
WXHWND hWnd = (WXHWND)_hWnd;
|
||||
wxPyAxBaseWindow* win = new wxPyAxBaseWindow;
|
||||
if (parent)
|
||||
parent->AddChild(win);
|
||||
win->SetEventHandler(win);
|
||||
win->SetHWND(hWnd);
|
||||
win->SubclassWin(hWnd);
|
||||
win->AdoptAttributesFromHWND();
|
||||
win->SetupColours();
|
||||
return win;
|
||||
}
|
||||
%End
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
typedef void WXMSG;
|
||||
|
||||
|
||||
class wxPyAxBaseWindow : wxWindow
|
||||
{
|
||||
public:
|
||||
wxPyAxBaseWindow(wxWindow* parent, const wxWindowID id=-1,
|
||||
const wxPoint& pos = wxDefaultPosition,
|
||||
const wxSize& size = wxDefaultSize,
|
||||
long style = 0,
|
||||
const wxString& name = wxPanelNameStr);
|
||||
wxPyAxBaseWindow();
|
||||
virtual bool MSWTranslateMessage(WXMSG* msg);
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//--------------------------------------------------------------------------
|
||||
// Name: src/stockobj.sip
|
||||
// Purpose: Wraper definition and some Python code for wxStockGDI and
|
||||
// Purpose: Wrapper definition and some Python code for wxStockGDI and
|
||||
// using it to initialize the stock objects like wx.BLUE_BRUSH,
|
||||
// etc. We're putting it here because wxStockGDI is not
|
||||
// documented, and probably should not be.
|
||||
|
||||
@@ -33,7 +33,8 @@ class mediactrl_Tests(wtc.WidgetTestCase):
|
||||
|
||||
def test_mediactrl4(self):
|
||||
evt = wx.media.MediaEvent()
|
||||
|
||||
|
||||
|
||||
def test_mediactrl5(self):
|
||||
wx.media.wxEVT_MEDIA_LOADED
|
||||
wx.media.wxEVT_MEDIA_STOP
|
||||
|
||||
31
unittests/test_metafile.py
Normal file
31
unittests/test_metafile.py
Normal file
@@ -0,0 +1,31 @@
|
||||
import unittest
|
||||
import wtc
|
||||
import wx
|
||||
import wx.msw
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
class MetafileDCTests(wtc.WidgetTestCase):
|
||||
|
||||
@unittest.skipIf('wxMSW' not in wx.PlatformInfo, "Metafile classes only imsplemented on Windows")
|
||||
def test_MetafileDC1(self):
|
||||
# Not testing with output file because it is not released soon enough
|
||||
# to be able to delete the file in this test, resulting in permission
|
||||
# errors.
|
||||
dc = wx.msw.MetafileDC()
|
||||
dc.DrawLine(0,0, 50,50)
|
||||
metafile = dc.Close()
|
||||
del dc
|
||||
|
||||
self.assertTrue(isinstance(metafile, wx.msw.Metafile))
|
||||
metafile.SetClipboard(50,50)
|
||||
metafile.Play(wx.ClientDC(self.frame))
|
||||
del metafile
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
27
wscript
27
wscript
@@ -225,10 +225,10 @@ def configure(conf):
|
||||
# ** Add code for new modules here
|
||||
|
||||
|
||||
# NOTE: This assumes that if the platform is not win32 (from
|
||||
# the test above) and not darwin then we must be using the
|
||||
# GTK2 port of wxWidgets. If we ever support other ports then
|
||||
# this code will need to be adjusted.
|
||||
# NOTE: This assumes that if the platform is not win32 (from the test
|
||||
# above) and not darwin then we must be using the GTK2 or GTK3 port of
|
||||
# wxWidgets. If we ever support other ports then this code will need
|
||||
# to be adjusted.
|
||||
if not isDarwin:
|
||||
if conf.options.gtk3:
|
||||
gtkflags = os.popen('pkg-config gtk+-3.0 --cflags', 'r').read()[:-1]
|
||||
@@ -288,8 +288,9 @@ from waflib.Configure import conf
|
||||
@conf
|
||||
def my_check_python_headers(conf):
|
||||
"""
|
||||
Check for headers and libraries necessary to extend or embed python by using the module *distutils*.
|
||||
On success the environment variables xxx_PYEXT and xxx_PYEMBED are added:
|
||||
Check for headers and libraries necessary to extend or embed python by
|
||||
using the module *distutils*. On success the environment variables
|
||||
xxx_PYEXT and xxx_PYEMBED are added:
|
||||
|
||||
* PYEXT: for compiling python extensions
|
||||
* PYEMBED: for embedding a python interpreter
|
||||
@@ -403,7 +404,7 @@ def my_check_python_headers(conf):
|
||||
|
||||
def build(bld):
|
||||
# Ensure that the directory containing this script is on the python
|
||||
# path for spawned commands so the builder and phoenix packages can be
|
||||
# sys.path for spawned commands so the builder and phoenix packages can be
|
||||
# found.
|
||||
thisdir = os.path.abspath(".")
|
||||
sys.path.insert(0, thisdir)
|
||||
@@ -578,6 +579,15 @@ def build(bld):
|
||||
)
|
||||
makeExtCopyRule(bld, '_media')
|
||||
|
||||
if isWindows:
|
||||
etg = loadETG('etg/_msw.py')
|
||||
bld(features = 'c cxx cxxshlib pyext',
|
||||
target = makeTargetName(bld, '_msw'),
|
||||
source = getEtgSipCppFiles(etg) + rc,
|
||||
uselib = 'WX WXPY',
|
||||
)
|
||||
makeExtCopyRule(bld, '_msw')
|
||||
|
||||
|
||||
|
||||
# ** Add code for new modules here
|
||||
@@ -621,8 +631,7 @@ def copyFileToPkg(task):
|
||||
from buildtools.config import opj
|
||||
src = task.inputs[0].abspath()
|
||||
tgt = task.outputs[0].abspath()
|
||||
#task.exec_command('touch %s' % tgt)
|
||||
open(tgt, "wb").close() # 'touch'
|
||||
open(tgt, "wb").close() # essentially just a unix 'touch' command
|
||||
tgt = opj(cfg.PKGDIR, os.path.basename(src))
|
||||
copy_file(src, tgt, verbose=1)
|
||||
return 0
|
||||
|
||||
@@ -29,6 +29,7 @@ this:
|
||||
"""
|
||||
|
||||
import wx
|
||||
import wx.msw
|
||||
|
||||
import ctypes as ct
|
||||
import ctypes.wintypes as wt
|
||||
@@ -57,13 +58,13 @@ WM_DESTROY = 2
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
class ActiveXCtrl(wx.PyAxBaseWindow):
|
||||
class ActiveXCtrl(wx.msw.PyAxBaseWindow):
|
||||
"""
|
||||
A wx.Window for hosting ActiveX controls. The COM interface of
|
||||
the ActiveX control is accessible through the ctrl property of
|
||||
this class, and this class is also set as the event sink for COM
|
||||
events originating from the ActiveX control. In other words, to
|
||||
catch the COM events you mearly have to derive from this class and
|
||||
catch the COM events you merely have to derive from this class and
|
||||
provide a method with the correct name. See the comtypes package
|
||||
documentation for more details.
|
||||
"""
|
||||
@@ -90,7 +91,7 @@ class ActiveXCtrl(wx.PyAxBaseWindow):
|
||||
# create the control
|
||||
atl.AtlAxWinInit()
|
||||
hInstance = kernel32.GetModuleHandleA(None)
|
||||
hwnd = user32.CreateWindowExA(0, "AtlAxWin", axID,
|
||||
hwnd = user32.CreateWindowExA(0, b"AtlAxWin", axID.encode("ASCII"),
|
||||
WS_CHILD | WS_VISIBLE
|
||||
| WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
|
||||
x,y, w,h, parent.GetHandle(), None,
|
||||
@@ -112,10 +113,12 @@ class ActiveXCtrl(wx.PyAxBaseWindow):
|
||||
self._evt_connections = []
|
||||
self.AddEventSink(self)
|
||||
|
||||
# Turn the window handle into a wx.Window and set this object to be that window
|
||||
win = wx.PyAxBaseWindow_FromHWND(parent, hwnd)
|
||||
self.PostCreate(win)
|
||||
wx.Window.__init__(self, parent, wxid, pos, size, style, name)
|
||||
|
||||
# Turn the window handle into a wx.Window and set this object to be that window
|
||||
#win = wx.PyAxBaseWindow_FromHWND(parent, hwnd)
|
||||
self.AssociateHandle(hwnd)
|
||||
|
||||
# Set some wx.Window properties
|
||||
if wxid == wx.ID_ANY:
|
||||
wxid = wx.Window.NewControlId()
|
||||
@@ -126,14 +129,16 @@ class ActiveXCtrl(wx.PyAxBaseWindow):
|
||||
self.Bind(wx.EVT_SET_FOCUS, self.OnSetFocus)
|
||||
self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
|
||||
self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroyWindow)
|
||||
|
||||
|
||||
|
||||
def AddEventSink(self, sink, interface=None):
|
||||
"""
|
||||
Add a new target to search for method names that match the COM
|
||||
Event names.
|
||||
"""
|
||||
self._evt_connections.append(cc.GetEvents(self._ax, sink, interface))
|
||||
|
||||
|
||||
|
||||
def GetCtrl(self):
|
||||
"""Easy access to the COM interface for the ActiveX Control"""
|
||||
return self._ax
|
||||
@@ -151,7 +156,7 @@ class ActiveXCtrl(wx.PyAxBaseWindow):
|
||||
if res == hr.S_OK:
|
||||
return True
|
||||
else:
|
||||
return wx.PyAxBaseWindow.MSWTranslateMessage(self, msg)
|
||||
return super(ActiveXCtrl, self).MSWTranslateMessage(msg)
|
||||
|
||||
|
||||
# TBD: Are the focus handlers needed?
|
||||
|
||||
@@ -90,8 +90,7 @@ def MakeActiveXClass(CoClass, eventClass=None, eventObj=None):
|
||||
}
|
||||
|
||||
# make a new class object
|
||||
import new
|
||||
classObj = new.classobj(className, baseClasses, classDict)
|
||||
classObj = type(className, baseClasses, classDict)
|
||||
return classObj
|
||||
|
||||
|
||||
@@ -103,7 +102,7 @@ def axw__init__(self, parent, ID=-1, pos=wx.DefaultPosition, size=wx.DefaultSize
|
||||
# init base classes
|
||||
pywin.mfc.activex.Control.__init__(self)
|
||||
wx.Window.__init__( self, parent, -1, pos, size, style|wx.NO_FULL_REPAINT_ON_RESIZE)
|
||||
self.this.own(False) # this should be set in wx.Window.__init__ when it calls _setOORInfo, but...
|
||||
#self.this.own(False) # this should be set in wx.Window.__init__ when it calls _setOORInfo, but...
|
||||
|
||||
win32ui.EnableControlContainer()
|
||||
self._eventObj = self._eventObj # move from class to instance
|
||||
@@ -126,7 +125,7 @@ def axw__init__(self, parent, ID=-1, pos=wx.DefaultPosition, size=wx.DefaultSize
|
||||
def axw__getattr__(self, attr):
|
||||
try:
|
||||
return pywin.mfc.activex.Control.__getattr__(self, attr)
|
||||
except AttributeError:
|
||||
except (AttributeError, win32ui.error):
|
||||
try:
|
||||
eo = self.__dict__['_eventObj']
|
||||
return getattr(eo, attr)
|
||||
|
||||
Reference in New Issue
Block a user