wx.stc.StyledTextCtrlはScintillaと言うエディタコントロールのラッパで、
シンタックスハイライトなどの機能が揃っており、
これを使うだけで、もうそれなりのエディタが出来てしまうのだが・・・
日本語入力のときに、変換候補の表示が変。
(カーソル位置ではなく、常に画面左上に表示される)
そこで、変換候補をカーソル位置に表示させてみた。
変換候補のフォントは適宜変更する必要がある。
IMEの候補の表示は次のページのソースを参考にした。
http://miau.s9.xrea.com/blog/index.php?itemid=876
from __future__ import with_statement, division, print_function import wx import wx.stc as stc from ctypes import windll from ctypes import Structure, c_long, c_byte, c_wchar_p, c_ulong, byref from ctypes import windll class POINT(Structure): _fields_ = [ ("x", c_long), ("y", c_long), ] class RECT(Structure): _fields_ = [ ("left", c_long), ("top", c_long), ("right", c_long), ("bottom", c_long), ] class COMPOSITIONFORM(Structure): _fields_ = [ ("dwStyle", c_ulong), ("ptCurrentPos", POINT), ("rcArea", RECT), ] class LOGFONT(Structure): _fields_ = [ ("lfHeight", c_long), ("lfWidth", c_long), ("lfEscapement", c_long), ("lfOrientation", c_long), ("lfWeight", c_long), ("lfItalic", c_byte), ("lfUnderline", c_byte), ("lfStrikeOut", c_byte), ("lfCharSet", c_byte), ("lfOutPrecision", c_byte), ("lfClipPrecision", c_byte), ("lfQuality", c_byte), ("lfPitchAndFamily", c_byte), ("lfFaceName", c_wchar_p), ] class StyledTextCtrl(stc.StyledTextCtrl): def __init__(self, *a, **kw): stc.StyledTextCtrl.__init__(self, *a, **kw) self.char_height = 32 self.font_facename = u"MSゴシック" self.Bind(stc.EVT_STC_PAINTED, self.OnEvent) wx.CallAfter(self.SetImeComposition) def IsImeOn(self): hIMC = windll.imm32.ImmGetContext(self.GetHandle()) status = windll.imm32.ImmGetOpenStatus(hIMC) windll.imm32.ImmReleaseContext(self.GetHandle(), hIMC) return status def SetImeComposition(self): if not self.IsImeOn(): return hIMC = windll.imm32.ImmGetContext( self.GetHandle()) lf = LOGFONT() lf.lfHeight = -self.char_height lf.lfWidth = 0 lf.lfPitchAndFamily = 1 & 48 # FIXED_PITCH & FF_MODERN lf.lfFaceName = self.font_facename windll.imm32.ImmSetCompositionFontW(hIMC, byref(lf)) cf = COMPOSITIONFORM() cf.dwStyle = 2 # CFS_POINT p = self.GetCurrentPos() x, y = self.PointFromPosition(p) cf.ptCurrentPos = POINT(x, y) windll.imm32.ImmSetCompositionWindow(hIMC, byref(cf)) windll.imm32.ImmReleaseContext(self.GetHandle(), hIMC) def OnEvent(self, event): event.Skip() self.SetImeComposition() def main(): app = wx.PySimpleApp() f = wx.Frame(None, -1) s = StyledTextCtrl(f, -1) f.Show() app.MainLoop() if __name__ == "__main__": main()