Skip to content

Commit 43126af

Browse files
authored
Merge pull request cztomczak#374 from mgdesign-fr/feature-pywin32-example
Repairing pywin32 example (cztomczak#224)
2 parents f51f96b + c95f52f commit 43126af

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed

examples/pywin32.py

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# Example of embedding CEF browser using the PyWin32 extension.
2+
# Tested with pywin32 version 219.
3+
4+
from cefpython3 import cefpython as cef
5+
6+
import distutils.sysconfig
7+
import math
8+
import os
9+
import platform
10+
import sys
11+
12+
import win32api
13+
import win32con
14+
import win32gui
15+
16+
WindowUtils = cef.WindowUtils()
17+
18+
# Platforms (Windows only)
19+
assert(platform.system() == "Windows")
20+
21+
def main(multi_threaded_message_loop):
22+
23+
check_versions()
24+
sys.excepthook = cef.ExceptHook # To shutdown all CEF processes on error
25+
26+
settings = {"multi_threaded_message_loop": 1 if multi_threaded_message_loop else 0,
27+
"remote_debugging_port": 2020}
28+
cef.Initialize(settings)
29+
30+
wndproc = {
31+
win32con.WM_CLOSE: CloseWindow,
32+
win32con.WM_DESTROY: QuitApplication,
33+
win32con.WM_SIZE: WindowUtils.OnSize,
34+
win32con.WM_SETFOCUS: WindowUtils.OnSetFocus,
35+
win32con.WM_ERASEBKGND: WindowUtils.OnEraseBackground
36+
}
37+
windowHandle = CreateWindow(title="pywin32 example", className="cefpython3_example", width=1024, height=768, windowProc=wndproc)
38+
39+
windowInfo = cef.WindowInfo()
40+
windowInfo.SetAsChild(windowHandle)
41+
42+
if(multi_threaded_message_loop):
43+
# when using multi-threaded message loop, CEF's UI thread is no more application's main thread
44+
cef.PostTask(cef.TID_UI, _createBrowserInUiThread, windowInfo, {}, "https://www.google.com/")
45+
win32gui.PumpMessages()
46+
47+
else:
48+
browser = _createBrowserInUiThread(windowInfo, {}, "https://www.google.com/")
49+
cef.MessageLoop()
50+
51+
cef.Shutdown()
52+
53+
54+
def check_versions():
55+
print("[pywin32.py] CEF Python {ver}".format(ver=cef.__version__))
56+
print("[pywin32.py] Python {ver} {arch}".format(ver=platform.python_version(), arch=platform.architecture()[0]))
57+
print("[pywin32.py] pywin32 {ver}".format(ver=GetPywin32Version()))
58+
assert cef.__version__ >= "55.3", "CEF Python v55.3+ required to run this"
59+
60+
61+
def _createBrowserInUiThread(windowInfo, settings, url):
62+
63+
assert(cef.IsThread(cef.TID_UI))
64+
browser = cef.CreateBrowserSync(windowInfo, settings, url)
65+
66+
67+
def CloseWindow(windowHandle, message, wparam, lparam):
68+
browser = cef.GetBrowserByWindowHandle(windowHandle)
69+
browser.CloseBrowser()
70+
return win32gui.DefWindowProc(windowHandle, message, wparam, lparam)
71+
72+
73+
def QuitApplication(windowHandle, message, wparam, lparam):
74+
win32gui.PostQuitMessage(0)
75+
return 0
76+
77+
78+
def CreateWindow(title, className, width, height, windowProc):
79+
80+
wndclass = win32gui.WNDCLASS()
81+
wndclass.hInstance = win32api.GetModuleHandle(None)
82+
wndclass.lpszClassName = className
83+
wndclass.style = win32con.CS_VREDRAW | win32con.CS_HREDRAW
84+
# win32con.CS_GLOBALCLASS
85+
wndclass.hbrBackground = win32con.COLOR_WINDOW
86+
wndclass.hCursor = win32gui.LoadCursor(0, win32con.IDC_ARROW)
87+
wndclass.lpfnWndProc = windowProc
88+
atomClass = win32gui.RegisterClass(wndclass)
89+
assert(atomClass != 0)
90+
91+
# Center window on the screen.
92+
screenx = win32api.GetSystemMetrics(win32con.SM_CXSCREEN)
93+
screeny = win32api.GetSystemMetrics(win32con.SM_CYSCREEN)
94+
xpos = int(math.floor((screenx - width) / 2))
95+
ypos = int(math.floor((screeny - height) / 2))
96+
if xpos < 0: xpos = 0
97+
if ypos < 0: ypos = 0
98+
99+
windowHandle = win32gui.CreateWindow(className, title,
100+
win32con.WS_OVERLAPPEDWINDOW | win32con.WS_CLIPCHILDREN | win32con.WS_VISIBLE,
101+
xpos, ypos, width, height, # xpos, ypos, width, height
102+
0, 0, wndclass.hInstance, None)
103+
104+
assert(windowHandle != 0)
105+
return windowHandle
106+
107+
108+
def GetPywin32Version():
109+
pth = distutils.sysconfig.get_python_lib(plat_specific=1)
110+
ver = open(os.path.join(pth, "pywin32.version.txt")).read().strip()
111+
return ver
112+
113+
114+
if __name__ == '__main__':
115+
116+
if "--multi_threaded_message_loop" in sys.argv:
117+
print("[pywin32.py] Message loop mode: CEF multi-threaded (best performance)")
118+
multi_threaded_message_loop = True
119+
else:
120+
print("[pywin32.py] Message loop mode: CEF single-threaded")
121+
multi_threaded_message_loop = False
122+
123+
main(multi_threaded_message_loop)

0 commit comments

Comments
 (0)