├── .gitattributes ├── .gitignore ├── Components ├── Controls │ ├── BaseControls.go │ ├── Forms.go │ ├── GraphicControls.go │ ├── ListBox.go │ ├── buttons.go │ └── editControls.go ├── DxControls │ ├── Scintilla │ │ ├── AMD64 │ │ │ └── SciLexer.dll │ │ ├── DxHtmlLexer.go │ │ ├── DxLanguageLexer.go │ │ ├── GScintillaEditor.go │ │ ├── MarginBand.go │ │ ├── X86 │ │ │ └── SciLexer.dll │ │ └── scintillaLib.go │ ├── WindowLessControls │ │ ├── DxCheckBox.go │ │ └── DxImage.go │ └── gminiblink │ │ ├── dll64 │ │ └── node.dll │ │ ├── mb_test.go │ │ ├── miniblikBrowser.go │ │ ├── miniblinkLib.go │ │ ├── miniblinkType.go │ │ └── test.html ├── NVisbleControls │ ├── menus.go │ ├── registry.go │ └── trayicon.go └── componentCore.go ├── Graphics ├── GraphicsCore.go ├── baseobj.go ├── bitmap.go └── canvas.go ├── README.md ├── WinApi ├── WinStructs.go ├── WindowsConsts.go ├── advapi32.go ├── comctl32.go ├── gdi32.go ├── kernel32.go ├── message.go ├── mpr.go ├── msimg32.go ├── opengl32.go ├── shellapi.go ├── user32.go ├── version.go ├── winsock2.go ├── wintrust.go └── wtsapi32.go ├── go.mod └── test ├── Dota2.ico ├── GVCL.png ├── PngUi.go ├── buildrc.bat ├── dota.ico ├── msgbox.exe.manifest ├── msgbox.go ├── msgbox.manifest ├── msgbox.syso ├── projectFilesBackup └── .idea │ └── workspace.xml └── testDraw.go /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /Components/Controls/Forms.go: -------------------------------------------------------------------------------- 1 | package controls 2 | 3 | import ( 4 | "github.com/suiyunonghen/GVCL/Components" 5 | "github.com/suiyunonghen/GVCL/WinApi" 6 | "github.com/suiyunonghen/GVCL/Graphics" 7 | "syscall" 8 | "context" 9 | "unsafe" 10 | ) 11 | 12 | var ( 13 | application *WApplication 14 | unActiveFormList *unActiveFormNode 15 | ) 16 | const( 17 | CANone=iota 18 | CAHide 19 | CAFree 20 | CAMinimize 21 | ) 22 | 23 | type OnFormCloseEvent func(sender interface{},closAction *int8) 24 | 25 | type GForm struct { 26 | GWinControl 27 | isSetModalresult bool 28 | fModalResult int8 29 | fisModalform bool 30 | OnClose OnFormCloseEvent 31 | fisDialog bool 32 | OnCreate Graphics.NotifyEvent 33 | OnShow Graphics.NotifyEvent 34 | } 35 | 36 | const( 37 | MrNone = 0 38 | MrOK = WinApi.IDOK 39 | MrCancle = WinApi.IDCANCEL 40 | MrYes = WinApi.IDYES 41 | MrNo = WinApi.IDNO 42 | MrIgnore = WinApi.IDIGNORE 43 | MrTryAgin = WinApi.IDTRYAGAIN 44 | MrRetry = WinApi.IDRETRY 45 | MrAbort = WinApi.IDABORT 46 | MrClose = WinApi.IDCLOSE 47 | MrContinue = WinApi.IDCONTINUE 48 | ) 49 | func (frm *GForm) SubInit() { 50 | frm.GWinControl.SubInit() 51 | frm.GComponent.SubInit(frm) 52 | frm.BindMessageMpas() 53 | frm.fVisible = false 54 | frm.fIsForm = true 55 | frm.fColor = Graphics.ClBtnFace 56 | frm.fwidth = 400 57 | frm.fheight = 300 58 | if frm.OnCreate!=nil{ 59 | frm.OnCreate(frm) 60 | } 61 | } 62 | 63 | type unActiveFormNode struct { 64 | formwnd syscall.Handle 65 | prev *unActiveFormNode 66 | } 67 | 68 | type ( 69 | SyncMethod func(params ...interface{}) //同步方法 70 | syncObject struct{ 71 | method SyncMethod 72 | params []interface{} //参数 73 | syncChan chan struct{} 74 | } 75 | 76 | WApplication struct { 77 | Components.GComponent 78 | fMainForm *GForm 79 | fForms []*GForm 80 | fRunning bool 81 | ShowMainForm bool 82 | OnMessage MessageEventHandler 83 | fChildObj interface{} 84 | ActiveForm *GForm 85 | fappIcon WinApi.HICON 86 | fcancelFunc context.CancelFunc 87 | fcontext context.Context 88 | synchronizeSignal chan syncObject //用来做goroutine同步的通道信号,一般发送的是要同步的函数和一个等待关闭的chan信号 89 | } 90 | ) 91 | 92 | func (obj *syncObject)runSyncMethod() { 93 | if obj.method!=nil{ 94 | obj.method(obj.params...) 95 | if obj.syncChan!=nil{ 96 | close(obj.syncChan) //关闭通道,通知完成了 97 | } 98 | } 99 | } 100 | 101 | func NewApplication()*WApplication { 102 | app := new(WApplication) 103 | app.fcontext,app.fcancelFunc = context.WithCancel(context.Background()) 104 | app.ShowMainForm =true 105 | app.synchronizeSignal = make(chan syncObject,1) 106 | application = app 107 | return app 108 | } 109 | 110 | 111 | func CurrentApplication()*WApplication { 112 | return application 113 | } 114 | 115 | func (app *WApplication) MainForm()*GForm { 116 | return app.fMainForm 117 | } 118 | 119 | func (app *WApplication)Context() context.Context { 120 | if app.fcontext != nil{ 121 | return app.fcontext 122 | } 123 | return context.Background() 124 | } 125 | 126 | func (app *WApplication)checkSyncMethod() { 127 | select{ 128 | case syncObj,ok := <- app.synchronizeSignal: 129 | if ok{ 130 | syncObj.runSyncMethod() //执行同步 131 | } 132 | default: 133 | 134 | } 135 | } 136 | 137 | func (app *WApplication) Run() { 138 | if application == nil{ 139 | application = app 140 | } 141 | app.fRunning = true 142 | if app.fMainForm != nil { 143 | if app.ShowMainForm { 144 | app.fMainForm.SetVisible(true) 145 | } 146 | if app.fappIcon==0{ 147 | if app.fappIcon = WinApi.LoadIcon(Hinstance,uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("MAINICON"))));app.fappIcon == 0{ 148 | app.fappIcon = WinApi.LoadIcon(Hinstance,uintptr(3)) 149 | if app.fappIcon == 0{ 150 | WinApi.ExtractIconEx("",0, nil, &app.fappIcon, 1); 151 | } 152 | } 153 | } 154 | WinApi.SendMessage(app.fMainForm.GetWindowHandle(),WinApi.WM_SETICON,uintptr(WinApi.ICON_BIG),uintptr(application.fappIcon)) 155 | for { 156 | select { 157 | case <- app.fcontext.Done(): 158 | app.fRunning = false 159 | return 160 | default: 161 | app.HandleMessage() 162 | } 163 | } 164 | } 165 | app.fRunning = false 166 | } 167 | 168 | func (app *WApplication)AppIcon()WinApi.HICON { 169 | if app.fappIcon == 0{ 170 | if app.fappIcon = WinApi.LoadIcon(Hinstance,uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("MAINICON"))));app.fappIcon == 0{ 171 | app.fappIcon = WinApi.LoadIcon(Hinstance,uintptr(3)) 172 | if app.fappIcon == 0{ 173 | WinApi.ExtractIconEx("",0, nil, &app.fappIcon, 1); 174 | } 175 | } 176 | } 177 | return app.fappIcon 178 | } 179 | 180 | 181 | func (frm *GForm) CreateParams(params *Components.GCreateParams) { 182 | frm.GWinControl.CreateParams(params) 183 | nstyle := int32(^(WinApi.WS_CHILD | WinApi.WS_GROUP | WinApi.WS_TABSTOP)) 184 | params.Style = uint32(int32(params.Style) & nstyle) 185 | if application.fMainForm != nil{ 186 | params.WndParent = application.fMainForm.fHandle 187 | } 188 | params.WinClassName = "GForm" 189 | if frm.fisDialog{ 190 | params.ExStyle = params.ExStyle | WinApi.WS_EX_DLGMODALFRAME | WinApi.WS_EX_WINDOWEDGE | WinApi.WS_EX_APPWINDOW 191 | params.Style = params.Style | WinApi.WS_CAPTION | WinApi.WS_POPUP | WinApi.WS_SYSMENU 192 | }else{ 193 | params.Style = params.Style | WinApi.WS_OVERLAPPEDWINDOW | WinApi.WS_CAPTION | WinApi.WS_THICKFRAME | WinApi.WS_MINIMIZEBOX | WinApi.WS_MAXIMIZEBOX | WinApi.WS_SYSMENU 194 | } 195 | nstyle = ^(WinApi.CS_HREDRAW | WinApi.CS_VREDRAW) 196 | params.WindowClass.Style = uint32(int32(params.WindowClass.Style) & nstyle) 197 | if frm == application.fMainForm{ 198 | params.ExStyle = params.ExStyle | WinApi.WS_EX_APPWINDOW 199 | } 200 | } 201 | 202 | func (frm *GForm)PaintWindow(dc WinApi.HDC)int32{ 203 | return frm.GWinControl.PaintWindow(dc) 204 | } 205 | 206 | func (frm *GForm)PaintBack(dc WinApi.HDC)int32 { 207 | return 1 208 | } 209 | 210 | func (frm *GForm)Close() { 211 | WinApi.SendMessage(frm.fHandle,WinApi.WM_CLOSE,0,0) 212 | frm.fVisible = false 213 | //if application.fMainForm == frm{ 214 | // application.fTerminate = true 215 | // WinApi.PostQuitMessage(0) 216 | //}else{ 217 | // WinApi.SendMessage(frm.fHandle,WinApi.WM_CLOSE,0,0) 218 | // frm.fVisible = false 219 | //} 220 | } 221 | 222 | func (frm *GForm)Show() { 223 | frm.isSetModalresult = false 224 | frm.fisModalform = false 225 | frm.SetVisible(true) 226 | WinApi.SetWindowPos(frm.fHandle, WinApi.HWND_TOP, 0, 0, 0, 0, 227 | WinApi.SWP_NOMOVE + WinApi.SWP_NOSIZE) 228 | } 229 | 230 | 231 | func DoDisableWindow(hwnd syscall.Handle,Data uintptr) uintptr { 232 | if WinApi.IsWindowVisible(hwnd) && WinApi.IsWindowEnabled(hwnd){ 233 | oldp := unActiveFormList 234 | unActiveFormList = new(unActiveFormNode) 235 | unActiveFormList.formwnd = hwnd 236 | unActiveFormList.prev = oldp 237 | WinApi.EnableWindow(hwnd,false) 238 | } 239 | return 1 240 | } 241 | 242 | func EnableDisableWindow() { 243 | if unActiveFormList != nil{ 244 | for{ 245 | WinApi.EnableWindow(unActiveFormList.formwnd,true) 246 | unActiveFormList = unActiveFormList.prev 247 | if unActiveFormList == nil{ 248 | break 249 | } 250 | } 251 | } 252 | } 253 | 254 | func (frm *GForm)ShowModal() int8 { 255 | //首先应该将所有后置的窗体都EnableFalse 256 | OldActiveForm := application.ActiveForm 257 | var oldActiveWnd syscall.Handle 258 | if OldActiveForm == nil{ 259 | oldActiveWnd = WinApi.GetActiveWindow() 260 | }else{ 261 | oldActiveWnd = OldActiveForm.fHandle 262 | } 263 | frm.fModalResult = MrNone 264 | enumproc := syscall.NewCallback(DoDisableWindow) 265 | WinApi.EnumThreadWindows(WinApi.GetCurrentThreadID(),enumproc,0) 266 | frm.Show() 267 | frm.fisModalform = true 268 | for{ 269 | application.HandleMessage() 270 | if frm.fModalResult != MrNone{ 271 | break 272 | } 273 | } 274 | EnableDisableWindow() 275 | WinApi.SetActiveWindow(oldActiveWnd) 276 | if OldActiveForm != nil{ 277 | application.ActiveForm = OldActiveForm 278 | } 279 | return frm.fModalResult 280 | } 281 | 282 | func (frm *GForm)SetModalResult(v int8) { 283 | frm.fModalResult = v 284 | frm.isSetModalresult = true 285 | frm.Close() 286 | } 287 | 288 | func (frm *GForm)ModalResult()int8 { 289 | return frm.fModalResult 290 | } 291 | 292 | func (frm *GForm)Set2DialogForm(v bool) { 293 | if frm.fisDialog != v{ 294 | frm.fisDialog = v 295 | if frm.HandleAllocated(){ 296 | 297 | } 298 | } 299 | } 300 | 301 | func (frm *GForm) WndProc(msg uint32, wparam, lparam uintptr) (result uintptr, msgDispatchNext bool) { 302 | result = 0 303 | msgDispatchNext = true 304 | switch msg { 305 | case WinApi.WM_CLOSE: 306 | msgDispatchNext = false 307 | var closeAction int8 = CAHide 308 | if frm.OnClose != nil{ 309 | frm.OnClose(frm,&closeAction) 310 | } 311 | switch closeAction { 312 | case CANone: 313 | if frm.fisModalform { 314 | frm.SetVisible(false) 315 | } 316 | frm.fModalResult = MrClose 317 | return 318 | case CAHide: 319 | frm.SetVisible(false) 320 | case CAFree: 321 | frm.SetVisible(false) 322 | WinApi.DestroyWindow(frm.fHandle) 323 | frm.fModalResult = MrClose 324 | return 325 | case CAMinimize: 326 | if frm.fisModalform { 327 | frm.SetVisible(false) 328 | frm.fModalResult = MrClose 329 | return 330 | } 331 | WinApi.ShowWindow(frm.GetWindowHandle(),WinApi.SW_SHOWMINIMIZED) 332 | } 333 | if frm.isSetModalresult{ 334 | 335 | }else{ 336 | frm.fModalResult = MrClose 337 | } 338 | case WinApi.WM_NULL: 339 | application.checkSyncMethod() 340 | case WinApi.WM_SHOWWINDOW: 341 | if wparam == 1 && frm.OnShow != nil{ 342 | frm.OnShow(frm) 343 | } 344 | case WinApi.WM_SETFOCUS: 345 | application.ActiveForm = frm 346 | default: 347 | result,msgDispatchNext = frm.GWinControl.WndProc(msg,wparam,lparam) 348 | } 349 | return 350 | } 351 | 352 | func NewForm() *GForm { 353 | frm := new(GForm) 354 | frm.SubInit() 355 | return frm 356 | } 357 | 358 | func (app *WApplication) CreateForm() *GForm { 359 | frm := NewForm() 360 | if app.fMainForm == nil { 361 | app.fMainForm = frm 362 | } 363 | app.fForms = append(app.fForms, frm) 364 | return frm 365 | } 366 | 367 | func (app *WApplication)WakeMainThread() { 368 | WinApi.PostMessage(app.fMainForm.fHandle,WinApi.WM_NULL,0,0) 369 | } 370 | 371 | //执行同步 372 | func (app *WApplication)Synchronize(syncMnd SyncMethod,params ...interface{}) { 373 | //通信发送 374 | if app.fMainForm == nil || app.fMainForm.HandleAllocated(){ 375 | notifychan := make(chan struct{}) 376 | app.synchronizeSignal <- syncObject{syncMnd,params,notifychan} 377 | app.WakeMainThread() //唤醒主线程 378 | select{ 379 | case <-notifychan: 380 | //完成之后退出咯 381 | return 382 | case <- app.fcontext.Done(): //退出 383 | return 384 | } 385 | }else{ 386 | //直接执行函数 387 | syncMnd(params) 388 | } 389 | } 390 | 391 | func (app *WApplication)Terminated()bool { 392 | select { 393 | case <-app.fcontext.Done(): 394 | return true 395 | default: 396 | return false 397 | } 398 | } 399 | 400 | func Synchronize(syncMnd SyncMethod,params ...interface{}) { 401 | if application != nil{ 402 | application.Synchronize(syncMnd) 403 | } 404 | } 405 | 406 | //消息处理 407 | func (app *WApplication) HandleMessage() { 408 | if app.fRunning{ 409 | msg := new(WinApi.MSG) 410 | if !app.ProcessMessage(msg) { 411 | app.idleMsg(msg) 412 | } 413 | } 414 | } 415 | 416 | 417 | func (app *WApplication)ProcessMessages() { 418 | msg := new(WinApi.MSG) 419 | for{ 420 | if !app.ProcessMessage(msg) { 421 | break 422 | } 423 | } 424 | } 425 | 426 | func (app *WApplication) ProcessMessage(msg *WinApi.MSG) bool { 427 | result := false 428 | defer func() { 429 | if r := recover(); r != nil { 430 | //处理异常 431 | println("异常:",r) 432 | } 433 | }() 434 | if msg.PeekMessage(0, 0, 0, WinApi.PM_REMOVE) { 435 | result = true 436 | if msg.Message != WinApi.WM_QUIT { 437 | if msg.Message == WinApi.WM_NULL{//检查是否可以同步 438 | application.checkSyncMethod() 439 | }else{ 440 | handled := false 441 | if app.OnMessage != nil { 442 | app.OnMessage(app, msg, &handled) 443 | } 444 | if !handled { 445 | msg.TranslateMessage() 446 | msg.DispatchMessage() 447 | } else { 448 | select{ 449 | case syncObj,ok := <- app.synchronizeSignal: 450 | if ok{ 451 | syncObj.runSyncMethod() //执行同步 452 | } 453 | default: 454 | app.idleMsg(msg) 455 | } 456 | } 457 | } 458 | } else { 459 | //执行完成 460 | app.doneApp() 461 | } 462 | } 463 | return result 464 | } 465 | 466 | func (app *WApplication) idleMsg(msg *WinApi.MSG) { 467 | WinApi.WaitMessage() 468 | } 469 | 470 | func (app *WApplication) doneApp() { 471 | app.fcancelFunc() 472 | WinApi.GlobalDeleteAtom(windowAtom) 473 | WinApi.GlobalDeleteAtom(controlAtom) 474 | } 475 | -------------------------------------------------------------------------------- /Components/Controls/GraphicControls.go: -------------------------------------------------------------------------------- 1 | package controls 2 | 3 | import ( 4 | "github.com/suiyunonghen/GVCL/WinApi" 5 | "github.com/suiyunonghen/GVCL/Graphics" 6 | "github.com/suiyunonghen/GVCL/Components" 7 | "reflect" 8 | ) 9 | 10 | type GLabel struct { 11 | GBaseControl 12 | fWordWrap bool 13 | fCaption string 14 | fAutoSize bool 15 | } 16 | 17 | func (lbl *GLabel) SubInit() { 18 | lbl.GBaseControl.SubInit() 19 | lbl.GComponent.SubInit(lbl) 20 | lbl.fwidth = 100 21 | lbl.fheight = 20 22 | lbl.fVisible = true 23 | lbl.fColor = Graphics.ClBtnFace 24 | } 25 | 26 | func (lbl *GLabel)calcSize() { 27 | cvs := Graphics.NewCanvas() 28 | fhandle := lbl.GetTargetCanvas(cvs) 29 | if fhandle == 0{ 30 | return 31 | } 32 | sz := new(WinApi.GSize) 33 | oldr := new(WinApi.Rect) 34 | cvs.RefreshCanvasState() 35 | oldr.Right = lbl.Width() 36 | oldr.Bottom = lbl.Height() 37 | cvs.Font().Assign(&lbl.Font) 38 | if cvs.TextExtent(lbl.fCaption,sz){ 39 | lbl.fwidth = sz.CX 40 | lbl.fheight = sz.CY 41 | if oldr.Right < sz.CX{ 42 | oldr.Right = sz.CX 43 | } 44 | if oldr.Bottom < sz.CY{ 45 | oldr.Bottom = sz.CY 46 | } 47 | if oldr.Right != sz.CX || oldr.Bottom != sz.CY{ 48 | oldr.OffsetRect(int(lbl.fleft),int(lbl.ftop)) 49 | if fhandle != 0{ 50 | WinApi.InvalidateRect(fhandle,oldr,false) 51 | } 52 | } 53 | } 54 | dc := cvs.GetHandle() 55 | cvs.SetHandle(0) 56 | WinApi.ReleaseDC(fhandle,dc) 57 | cvs.Destroy() 58 | } 59 | 60 | func (lbl *GLabel)SetAutoSize(v bool) { 61 | if lbl.fAutoSize != v{ 62 | lbl.fAutoSize = v 63 | if lbl.fAutoSize{ 64 | if pc := lbl.GetParent();pc!=nil && pc.HandleAllocated(){ 65 | lbl.calcSize() 66 | } 67 | } 68 | } 69 | } 70 | 71 | func (lbl *GLabel)AfterParentWndCreate() { 72 | if lbl.fAutoSize{ 73 | lbl.calcSize() 74 | } 75 | } 76 | 77 | func (lbl *GLabel)Paint(cvs Graphics.ICanvas) { 78 | r := WinApi.Rect{0,0,lbl.Width(),lbl.Height()} 79 | var drawflags uint = WinApi.DT_LEFT | WinApi.DT_TOP | WinApi.DT_CALCRECT 80 | if !lbl.fTrasparent{ 81 | cvs.FillRect(&r) 82 | } 83 | if lbl.fWordWrap{ 84 | drawflags = WinApi.DT_CENTER | WinApi.DT_VCENTER | WinApi.DT_WORDBREAK 85 | }else{ 86 | drawflags = WinApi.DT_CENTER | WinApi.DT_VCENTER | WinApi.DT_SINGLELINE 87 | } 88 | if lbl.fCaption != ""{ 89 | brush := cvs.Brush() 90 | brush.BrushStyle = Graphics.BSClear 91 | brush.Change() 92 | WinApi.DrawText(cvs.GetHandle(),lbl.fCaption,-1,&r,drawflags) 93 | } 94 | } 95 | 96 | 97 | 98 | func (lbl *GLabel)SetCaption(cap string) { 99 | if lbl.fCaption != cap{ 100 | lbl.fCaption = cap 101 | if lbl.fAutoSize{ 102 | lbl.calcSize() 103 | } 104 | } 105 | } 106 | 107 | func NewLabel(aParent Components.IWincontrol) *GLabel { 108 | pType := reflect.TypeOf(aParent) 109 | hasWincontrol := false 110 | if pType.Kind() == reflect.Ptr { 111 | _, hasWincontrol = pType.Elem().FieldByName("GWinControl") 112 | } 113 | if hasWincontrol { 114 | lbl := new(GLabel) 115 | lbl.SubInit() 116 | lbl.SetParent(aParent) 117 | return lbl 118 | } 119 | return nil 120 | } 121 | -------------------------------------------------------------------------------- /Components/Controls/ListBox.go: -------------------------------------------------------------------------------- 1 | package controls 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "github.com/suiyunonghen/DxCommonLib" 7 | "github.com/suiyunonghen/GVCL/Components" 8 | "github.com/suiyunonghen/GVCL/Graphics" 9 | "github.com/suiyunonghen/GVCL/WinApi" 10 | "reflect" 11 | "strings" 12 | "syscall" 13 | "unsafe" 14 | ) 15 | 16 | type ( 17 | ListBoxStyle int16 18 | 19 | gListBoxStrings struct { 20 | DxCommonLib.GStringList 21 | fListBox *GListBox 22 | } 23 | GListBox struct { 24 | GWinControl 25 | fItemIndex int 26 | fItems *gListBoxStrings 27 | OnItemClick Graphics.NotifyEvent 28 | OnItemDblClick Graphics.NotifyEvent 29 | fStyle ListBoxStyle 30 | } 31 | ) 32 | 33 | const ( 34 | LBStandard ListBoxStyle = iota 35 | LBOwnerDrawFixed 36 | LBOwnerDrawVariable 37 | LBVirtual 38 | LBVirtualOwnerDraw 39 | ) 40 | 41 | func (list *gListBoxStrings) Count() int { 42 | if list.fListBox.fHandle == 0 { 43 | return list.GStringList.Count() 44 | } 45 | return int(WinApi.SendMessage(list.fListBox.fHandle, WinApi.LB_GETCOUNT, 0, 0)) 46 | } 47 | 48 | func (list *gListBoxStrings) Strings(index int) string { 49 | if list.fListBox.fHandle == 0 { 50 | return list.GStringList.Strings(index) 51 | } 52 | if list.fListBox.fStyle >= LBVirtual { 53 | return "" //虚拟自填充数据的暂时不处理 54 | } else { 55 | l := WinApi.SendMessage(list.fListBox.fHandle, WinApi.LB_GETTEXTLEN, uintptr(index), 0) 56 | if l == -1 { 57 | panic("指定的索引不存在") 58 | } else if l != 0 { 59 | mp := make([]uint16, l+1) 60 | WinApi.SendMessage(list.fListBox.fHandle, WinApi.LB_GETTEXT, uintptr(index), uintptr(unsafe.Pointer(&mp[0]))) 61 | return syscall.UTF16ToString(mp) 62 | } 63 | } 64 | return "" 65 | } 66 | 67 | func (list *gListBoxStrings) SetStrings(index int, str string) { 68 | if list.fListBox.fHandle == 0 { 69 | list.GStringList.SetStrings(index, str) 70 | return 71 | } 72 | i := list.fListBox.GetItemIndex() 73 | tmpdata := list.fListBox.GetItemData(index) 74 | list.fListBox.SetItemData(index, 0) 75 | list.Delete(index) 76 | list.Insert(index, str) 77 | list.fListBox.SetItemData(index, tmpdata) 78 | list.fListBox.SetItemIndex(i) 79 | } 80 | 81 | func (list *gListBoxStrings) Text() string { 82 | if list.fListBox.fHandle == 0 { 83 | return list.GStringList.Text() 84 | } 85 | var bf bytes.Buffer 86 | tc := list.Count() 87 | for i := 0; i < tc; i++ { 88 | bf.WriteString(list.Strings(i)) 89 | if i < tc-1 { 90 | bf.WriteString(`\r\n`) 91 | } 92 | } 93 | return bf.String() 94 | } 95 | 96 | func (list *gListBoxStrings) Add(str string) { 97 | if list.fListBox.fHandle == 0 { 98 | list.GStringList.Add(str) 99 | return 100 | } 101 | if list.fListBox.fStyle < LBVirtual { 102 | mp := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(str))) 103 | WinApi.SendMessage(list.fListBox.fHandle, WinApi.LB_ADDSTRING, 0, mp) 104 | } 105 | } 106 | 107 | func (list *gListBoxStrings) SetText(text string) { 108 | if list.fListBox.fHandle == 0 { 109 | list.GStringList.SetText(text) 110 | return 111 | } 112 | list.Clear() 113 | strs := strings.Split(text, `\r\n`) 114 | for _, str := range strs { 115 | list.Add(str) 116 | } 117 | } 118 | 119 | func (list *gListBoxStrings) LoadFromFile(fileName string) { 120 | if list.fListBox.fHandle == 0 { 121 | list.GStringList.LoadFromFile(fileName) 122 | return 123 | } 124 | } 125 | 126 | func (list *gListBoxStrings) SaveToFile(fileName string) { 127 | if list.fListBox.fHandle == 0 { 128 | list.GStringList.SaveToFile(fileName) 129 | return 130 | } 131 | } 132 | 133 | func (list *gListBoxStrings) Clear() { 134 | if list.fListBox.fHandle == 0 { 135 | list.GStringList.Clear() 136 | return 137 | } 138 | if list.fListBox.fStyle < LBVirtual { 139 | WinApi.SendMessage(list.fListBox.fHandle, WinApi.LB_RESETCONTENT, 0, 0) 140 | } 141 | } 142 | 143 | func (list *gListBoxStrings) Insert(Index int, str string) { 144 | if list.fListBox.fHandle == 0 { 145 | list.GStringList.Insert(Index, str) 146 | return 147 | } 148 | if list.fListBox.fStyle < LBVirtual { 149 | mp := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(str))) 150 | WinApi.SendMessage(list.fListBox.fHandle, WinApi.LB_INSERTSTRING, uintptr(Index), mp) 151 | } 152 | } 153 | 154 | func (list *gListBoxStrings) Delete(index int) { 155 | if list.fListBox.fHandle == 0 { 156 | list.GStringList.Delete(index) 157 | return 158 | } 159 | WinApi.SendMessage(list.fListBox.fHandle, WinApi.LB_DELETESTRING, uintptr(index), 0) 160 | } 161 | 162 | func (list *gListBoxStrings) AddStrings(strs DxCommonLib.IStrings) { 163 | if list.fListBox.fHandle == 0 { 164 | list.GStringList.AddStrings(strs) 165 | return 166 | } 167 | for i := 0; i < strs.Count(); i++ { 168 | list.Add(strs.Strings(i)) 169 | } 170 | } 171 | 172 | func (list *gListBoxStrings) IndexOf(str string) int { 173 | if list.fListBox.fHandle == 0 { 174 | return list.GStringList.IndexOf(str) 175 | } 176 | if list.fListBox.fStyle < LBVirtual { 177 | mp := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(str))) 178 | m := -1 179 | return int(WinApi.SendMessage(list.fListBox.fHandle, WinApi.LB_FINDSTRINGEXACT, uintptr(m), mp)) 180 | } 181 | return -1 182 | } 183 | 184 | func (list *gListBoxStrings) AddPair(Name, Value string) { 185 | if list.fListBox.fHandle == 0 { 186 | list.GStringList.AddPair(Name, Value) 187 | return 188 | } 189 | list.Add(fmt.Sprintf("%s=%s", Name, Value)) 190 | } 191 | 192 | func (lst *gListBoxStrings) IndexOfName(Name string) int { 193 | if lst.fListBox.fHandle == 0 { 194 | return lst.GStringList.IndexOfName(Name) 195 | } 196 | for i := 0; i < lst.Count(); i++ { 197 | v := lst.Strings(i) 198 | if eidx := strings.IndexByte(v, '='); eidx > 0 { 199 | bt := []byte(v) 200 | if string(bt[:eidx]) == Name { 201 | return i 202 | } 203 | } 204 | } 205 | return -1 206 | } 207 | 208 | func (lst *gListBoxStrings) ValueFromIndex(index int) string { 209 | if lst.fListBox.fHandle == 0 { 210 | return lst.GStringList.ValueFromIndex(index) 211 | } 212 | tc := lst.Count() 213 | if tc == 0 { 214 | return "" 215 | } 216 | if index >= 0 && index < tc { 217 | str := lst.Strings(index) 218 | if idx := strings.IndexByte(str, '='); idx > 0 { 219 | bt := []byte(str) 220 | return DxCommonLib.FastByte2String(bt[idx+1:]) 221 | } 222 | return "" 223 | } 224 | return "" 225 | } 226 | 227 | func (list *gListBoxStrings) ValueByName(Name string) string { 228 | if list.fListBox.fHandle == 0 { 229 | return list.GStringList.ValueByName(Name) 230 | } 231 | for i := 0; i < list.Count(); i++ { 232 | v := list.Strings(i) 233 | if eidx := strings.IndexByte(v, '='); eidx > 0 { 234 | bt := []byte(v) 235 | if string(bt[:eidx]) == Name { 236 | return DxCommonLib.FastByte2String(bt[eidx+1:]) 237 | } 238 | } 239 | } 240 | return "" 241 | } 242 | 243 | func (list *gListBoxStrings) Names(Index int) string { 244 | if list.fListBox.fHandle == 0 { 245 | return list.GStringList.Names(Index) 246 | } 247 | if list.Count() == 0 { 248 | return "" 249 | } 250 | if Index >= 0 && Index < list.Count() { 251 | str := list.Strings(Index) 252 | if idx := strings.IndexByte(str, '='); idx > 0 { 253 | bt := []byte(str) 254 | return DxCommonLib.FastByte2String(bt[:idx]) 255 | } 256 | return "" 257 | } 258 | return "" 259 | } 260 | 261 | func (list *gListBoxStrings) AsSlice() []string { 262 | if list.fListBox.fHandle == 0 { 263 | return list.GStringList.AsSlice() 264 | } 265 | tc := list.Count() 266 | result := make([]string, tc) 267 | for i := 0; i < tc; i++ { 268 | result[i] = list.Strings(i) 269 | } 270 | return result 271 | } 272 | 273 | func (list *gListBoxStrings) AddSlice(strs []string) { 274 | if list.fListBox.fHandle == 0 { 275 | list.GStringList.AddSlice(strs) 276 | return 277 | } 278 | for _, str := range strs { 279 | list.Add(str) 280 | } 281 | } 282 | 283 | func (lstbox *GListBox) SubInit() { 284 | if lstbox.fItems == nil { 285 | lstbox.fItems = &gListBoxStrings{fListBox: lstbox} 286 | } 287 | lstbox.GWinControl.SubInit() 288 | lstbox.GComponent.SubInit(lstbox) 289 | } 290 | 291 | func (lstbox *GListBox) GetItemIndex() int { 292 | return int(WinApi.SendMessage(lstbox.fHandle, WinApi.LB_GETCURSEL, 0, 0)) 293 | } 294 | 295 | func (lstbox *GListBox) SetItemIndex(idx int) { 296 | if lstbox.HandleAllocated() { 297 | if lstbox.GetItemIndex() != idx { 298 | WinApi.SendMessage(lstbox.fHandle, WinApi.LB_SETCURSEL, uintptr(idx), 0) 299 | } 300 | } else { 301 | lstbox.fItemIndex = idx 302 | } 303 | } 304 | 305 | func (lstbox *GListBox) CreateParams(params *Components.GCreateParams) { 306 | lstbox.GWinControl.CreateParams(params) 307 | lstbox.InitSubclassParams(params, "LISTBOX") 308 | var lstyle int32 = 0 309 | switch lstbox.fStyle { 310 | case LBStandard: 311 | lstyle = 0 312 | case LBOwnerDrawVariable: 313 | lstyle = WinApi.LBS_OWNERDRAWVARIABLE 314 | default: 315 | lstyle = WinApi.LBS_OWNERDRAWFIXED 316 | } 317 | params.Style = params.Style | (WinApi.WS_HSCROLL | WinApi.WS_VSCROLL | WinApi.LBS_HASSTRINGS | WinApi.LBS_NOTIFY) | 318 | uint32(lstyle) | WinApi.LBS_USETABSTOPS | WinApi.WS_TABSTOP 319 | params.ExStyle = params.ExStyle | WinApi.WS_EX_CLIENTEDGE 320 | lstyle = ^(WinApi.CS_HREDRAW | WinApi.CS_VREDRAW) 321 | params.WindowClass.Style = params.WindowClass.Style & uint32(lstyle) 322 | params.WinClassName = "GListBox" 323 | } 324 | 325 | func (lstbox *GListBox) GetItemData(index int) int { 326 | return int(WinApi.SendMessage(lstbox.fHandle, WinApi.LB_GETITEMDATA, uintptr(index), 0)) 327 | } 328 | 329 | func (lstbox *GListBox) SetItemData(index, AData int) { 330 | WinApi.SendMessage(lstbox.fHandle, WinApi.LB_SETITEMDATA, uintptr(index), uintptr(AData)) 331 | } 332 | 333 | func (lstbox *GListBox) Items() DxCommonLib.IStrings { 334 | return lstbox.fItems 335 | } 336 | 337 | func (lstbox *GListBox) CreateWindowHandle(params *Components.GCreateParams) bool { 338 | if lstbox.GWinControl.CreateWindowHandle(params) { 339 | for i := 0; i < lstbox.fItems.GStringList.Count(); i++ { 340 | lp := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lstbox.fItems.GStringList.Strings(i)))) 341 | WinApi.SendMessage(lstbox.fHandle, WinApi.LB_ADDSTRING, 0, lp) 342 | } 343 | lstbox.fItems.GStringList.Clear() 344 | WinApi.SendMessage(lstbox.fHandle, WinApi.LB_SETCURSEL, uintptr(lstbox.fItemIndex), 0) 345 | return true 346 | } 347 | return false 348 | } 349 | 350 | func (lstbox *GListBox) WndProc(msg uint32, wparam, lparam uintptr) (result uintptr, msgDispatchNext bool) { 351 | result = 0 352 | msgDispatchNext = false 353 | switch msg { 354 | case WinApi.WM_COMMAND: 355 | notifycode := WinApi.HiWord(uint32(wparam)) 356 | switch notifycode { 357 | case WinApi.LBN_SELCHANGE: 358 | if lstbox.OnItemClick != nil { 359 | lstbox.OnItemClick(lstbox) 360 | } 361 | case WinApi.LBN_DBLCLK: 362 | if lstbox.OnItemDblClick != nil { 363 | lstbox.OnItemDblClick(lstbox) 364 | } 365 | case WinApi.LBN_SELCANCEL: 366 | if lstbox.OnItemClick != nil { 367 | lstbox.OnItemClick(lstbox) 368 | } 369 | } 370 | default: 371 | result = WinApi.CallWindowProc(lstbox.FDefWndProc, lstbox.GetWindowHandle(), msg, wparam, lparam) 372 | } 373 | return 374 | } 375 | 376 | func (lstbox *GListBox) GetTopIndex() int { 377 | return int(WinApi.SendMessage(lstbox.fHandle, WinApi.LB_GETTOPINDEX, 0, 0)) 378 | } 379 | 380 | func (lstbox *GListBox) SetTopIndex(v int) { 381 | WinApi.SendMessage(lstbox.fHandle, WinApi.LB_SETTOPINDEX, uintptr(v), 0) 382 | } 383 | 384 | func (lstbox *GListBox) ItemAtPos(x, y int) int { 385 | r := WinApi.Rect{} 386 | p := WinApi.POINT{int32(x), int32(y)} 387 | if r.GetClientRect(lstbox.fHandle) && r.PtInRect(&p) { 388 | for tpidx := int(WinApi.SendMessage(lstbox.fHandle, WinApi.LB_GETTOPINDEX, 0, 0)); tpidx < lstbox.fItems.Count(); tpidx++ { 389 | lstbox.Perform(WinApi.LB_GETITEMRECT, uintptr(tpidx), uintptr(unsafe.Pointer(&r))) 390 | if r.PtInRect(&p) { 391 | return tpidx 392 | } 393 | } 394 | } 395 | return -1 396 | } 397 | 398 | func (lstbox *GListBox) ItemRect(Index int) WinApi.Rect { 399 | r := WinApi.Rect{} 400 | Count := lstbox.fItems.Count() 401 | if Index < Count { 402 | lstbox.Perform(WinApi.LB_GETITEMRECT, uintptr(Index), uintptr(unsafe.Pointer(&r))) 403 | } else if Index == Count { 404 | lstbox.Perform(WinApi.LB_GETITEMRECT, uintptr(Index-1), uintptr(unsafe.Pointer(&r))) 405 | r.OffsetRect(0, int(r.Height())) 406 | } 407 | return r 408 | } 409 | 410 | func NewListBox(aParent Components.IWincontrol) *GListBox { 411 | pType := reflect.TypeOf(aParent) 412 | hasWincontrol := false 413 | if pType.Kind() == reflect.Ptr { 414 | _, hasWincontrol = pType.Elem().FieldByName("GWinControl") 415 | } 416 | if hasWincontrol { 417 | lstbox := new(GListBox) 418 | lstbox.SubInit() 419 | lstbox.fwidth = 121 420 | lstbox.fVisible = true 421 | lstbox.fheight = 97 422 | lstbox.fColor = Graphics.ClWhite 423 | lstbox.SetParent(aParent) 424 | return lstbox 425 | } 426 | return nil 427 | } 428 | -------------------------------------------------------------------------------- /Components/Controls/buttons.go: -------------------------------------------------------------------------------- 1 | package controls 2 | 3 | import ( 4 | "github.com/suiyunonghen/GVCL/Components" 5 | "github.com/suiyunonghen/GVCL/Graphics" 6 | "github.com/suiyunonghen/GVCL/WinApi" 7 | "reflect" 8 | ) 9 | 10 | type GButton struct { 11 | GWinControl 12 | fDefault bool 13 | OnClick Graphics.NotifyEvent 14 | } 15 | 16 | func (btn *GButton) SetDefault(v bool) { 17 | btn.fDefault = v 18 | } 19 | 20 | func (btn *GButton) Default() bool { 21 | return btn.fDefault 22 | } 23 | 24 | func (btn *GButton) SubInit() { 25 | btn.GWinControl.SubInit() 26 | btn.GComponent.SubInit(btn) 27 | } 28 | 29 | func (btn *GButton) CreateParams(params *Components.GCreateParams) { 30 | btn.GWinControl.CreateParams(params) 31 | btn.InitSubclassParams(params, "BUTTON") 32 | if btn.fDefault { 33 | params.Style = params.Style | WinApi.BS_DEFPUSHBUTTON 34 | } else { 35 | params.Style = params.Style | WinApi.BS_PUSHBUTTON 36 | } 37 | params.WinClassName = "GButton" 38 | } 39 | 40 | func (btn *GButton) WndProc(msg uint32, wparam, lparam uintptr) (result uintptr, msgDispatchNext bool) { 41 | result = 0 42 | msgDispatchNext = false 43 | switch msg { 44 | case WinApi.WM_COMMAND: //按钮事件 45 | notifycode := WinApi.HiWord(uint32(wparam)) 46 | if notifycode == uint16(WinApi.BN_CLICKED) { 47 | if btn.OnClick != nil { 48 | btn.OnClick(btn) 49 | } 50 | } 51 | default: 52 | result = WinApi.CallWindowProc(btn.FDefWndProc, btn.fHandle, msg, wparam, lparam) 53 | } 54 | return 55 | } 56 | 57 | func NewButton(aParent Components.IWincontrol) *GButton { 58 | pType := reflect.TypeOf(aParent) 59 | hasWincontrol := false 60 | if pType.Kind() == reflect.Ptr { 61 | _, hasWincontrol = pType.Elem().FieldByName("GWinControl") 62 | } 63 | if hasWincontrol { 64 | btn := new(GButton) 65 | btn.SubInit() 66 | btn.SetParent(aParent) 67 | btn.SetWidth(80) 68 | btn.SetVisible(true) 69 | btn.SetHeight(30) 70 | return btn 71 | } 72 | return nil 73 | } 74 | -------------------------------------------------------------------------------- /Components/Controls/editControls.go: -------------------------------------------------------------------------------- 1 | package controls 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "github.com/suiyunonghen/DxCommonLib" 7 | "github.com/suiyunonghen/GVCL/Components" 8 | "github.com/suiyunonghen/GVCL/Graphics" 9 | "github.com/suiyunonghen/GVCL/WinApi" 10 | "reflect" 11 | "strings" 12 | "syscall" 13 | "unsafe" 14 | ) 15 | 16 | type GEdit struct { 17 | GWinControl 18 | fDefault bool 19 | OnChange Graphics.NotifyEvent 20 | } 21 | 22 | func (edt *GEdit) SubInit() { 23 | edt.GWinControl.SubInit() 24 | edt.GComponent.SubInit(edt) 25 | } 26 | 27 | func (edt *GEdit) CreateParams(params *Components.GCreateParams) { 28 | edt.GWinControl.CreateParams(params) 29 | edt.InitSubclassParams(params, "EDIT") 30 | params.Style = params.Style | WinApi.ES_AUTOHSCROLL | WinApi.ES_AUTOVSCROLL | WinApi.ES_LEFT 31 | params.ExStyle = params.ExStyle | WinApi.WS_EX_CLIENTEDGE 32 | params.WinClassName = "GEdit" 33 | } 34 | 35 | func (edt *GEdit) WndProc(msg uint32, wparam, lparam uintptr) (result uintptr, msgDispatchNext bool) { 36 | msgDispatchNext = false 37 | if msg == WinApi.WM_COMMAND { 38 | notifycode := WinApi.HiWord(uint32(wparam)) 39 | if notifycode == WinApi.EN_CHANGE { 40 | if edt.OnChange != nil { 41 | edt.OnChange(edt) 42 | } 43 | } 44 | } 45 | result = WinApi.CallWindowProc(edt.FDefWndProc, edt.fHandle, msg, wparam, lparam) 46 | return 47 | } 48 | 49 | func NewEdit(aParent Components.IWincontrol) *GEdit { 50 | pType := reflect.TypeOf(aParent) 51 | hasWincontrol := false 52 | if pType.Kind() == reflect.Ptr { 53 | _, hasWincontrol = pType.Elem().FieldByName("GWinControl") 54 | } 55 | if hasWincontrol { 56 | edt := new(GEdit) 57 | edt.SubInit() 58 | edt.SetParent(aParent) 59 | edt.SetWidth(80) 60 | edt.SetVisible(true) 61 | edt.SetHeight(30) 62 | return edt 63 | } 64 | return nil 65 | } 66 | 67 | type ( 68 | GComboBoxStyle int16 69 | gComboBoxStrings struct { 70 | DxCommonLib.GStringList 71 | fCombobox *GCombobox 72 | } 73 | GCombobox struct { 74 | GWinControl 75 | fItemIndex int 76 | fItems *gComboBoxStrings 77 | fStyle GComboBoxStyle 78 | fListHandle syscall.Handle 79 | fEditHandle syscall.Handle 80 | fDefListProc uintptr 81 | fDefEditProc uintptr 82 | fDropDownCount int32 83 | OnChange Graphics.NotifyEvent 84 | OnSelect Graphics.NotifyEvent 85 | OnCloseUp Graphics.NotifyEvent 86 | } 87 | ) 88 | 89 | const ( 90 | CSDropDown GComboBoxStyle = iota 91 | CSSimple 92 | CSDropDownList 93 | CSOwnerDrawFixed 94 | CSOwnerDrawVariable 95 | ) 96 | 97 | func (list *gComboBoxStrings) Count() int { 98 | if list.fCombobox.fHandle == 0 { 99 | return list.GStringList.Count() 100 | } 101 | return int(WinApi.SendMessage(list.fCombobox.fHandle, WinApi.CB_GETCOUNT, 0, 0)) 102 | } 103 | 104 | func (list *gComboBoxStrings) Strings(index int) string { 105 | if list.fCombobox.fHandle == 0 { 106 | return list.GStringList.Strings(index) 107 | } 108 | l := WinApi.SendMessage(list.fCombobox.fHandle, WinApi.CB_GETLBTEXTLEN, uintptr(index), 0) 109 | if l == -1 { 110 | panic("指定的索引不存在") 111 | } else if l != 0 { 112 | mp := make([]uint16, l+1) 113 | WinApi.SendMessage(list.fCombobox.fHandle, WinApi.CB_GETLBTEXT, uintptr(index), uintptr(unsafe.Pointer(&mp[0]))) 114 | return syscall.UTF16ToString(mp) 115 | } 116 | return "" 117 | } 118 | 119 | func (list *gComboBoxStrings) SetStrings(index int, str string) { 120 | if list.fCombobox.fHandle == 0 { 121 | list.GStringList.SetStrings(index, str) 122 | return 123 | } 124 | i := list.fCombobox.GetItemIndex() 125 | list.Delete(index) 126 | list.Insert(index, str) 127 | list.fCombobox.SetItemIndex(i) 128 | } 129 | 130 | func (list *gComboBoxStrings) Text() string { 131 | if list.fCombobox.fHandle == 0 { 132 | return list.GStringList.Text() 133 | } 134 | var bf bytes.Buffer 135 | tc := list.Count() 136 | for i := 0; i < tc; i++ { 137 | bf.WriteString(list.Strings(i)) 138 | if i < tc-1 { 139 | bf.WriteString(`\r\n`) 140 | } 141 | } 142 | return bf.String() 143 | } 144 | 145 | func (list *gComboBoxStrings) Add(str string) { 146 | if list.fCombobox.fHandle == 0 { 147 | list.GStringList.Add(str) 148 | return 149 | } 150 | mp := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(str))) 151 | WinApi.SendMessage(list.fCombobox.fHandle, WinApi.CB_ADDSTRING, 0, mp) 152 | } 153 | 154 | func (list *gComboBoxStrings) SetText(text string) { 155 | if list.fCombobox.fHandle == 0 { 156 | list.GStringList.SetText(text) 157 | return 158 | } 159 | list.Clear() 160 | strs := strings.Split(text, `\r\n`) 161 | for _, str := range strs { 162 | list.Add(str) 163 | } 164 | } 165 | 166 | func (list *gComboBoxStrings) LoadFromFile(fileName string) { 167 | if list.fCombobox.fHandle == 0 { 168 | list.GStringList.LoadFromFile(fileName) 169 | return 170 | } 171 | } 172 | 173 | func (list *gComboBoxStrings) SaveToFile(fileName string) { 174 | if list.fCombobox.fHandle == 0 { 175 | list.GStringList.SaveToFile(fileName) 176 | return 177 | } 178 | } 179 | 180 | func (list *gComboBoxStrings) Clear() { 181 | if list.fCombobox.fHandle == 0 { 182 | list.GStringList.Clear() 183 | return 184 | } 185 | WinApi.SendMessage(list.fCombobox.fHandle, WinApi.CB_RESETCONTENT, 0, 0) 186 | } 187 | 188 | func (list *gComboBoxStrings) Insert(Index int, str string) { 189 | if list.fCombobox.fHandle == 0 { 190 | list.GStringList.Insert(Index, str) 191 | return 192 | } 193 | mp := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(str))) 194 | WinApi.SendMessage(list.fCombobox.fHandle, WinApi.CB_INSERTSTRING, uintptr(Index), mp) 195 | } 196 | 197 | func (list *gComboBoxStrings) Delete(index int) { 198 | if list.fCombobox.fHandle == 0 { 199 | list.GStringList.Delete(index) 200 | return 201 | } 202 | WinApi.SendMessage(list.fCombobox.fHandle, WinApi.CB_DELETESTRING, uintptr(index), 0) 203 | } 204 | 205 | func (list *gComboBoxStrings) AddStrings(strs DxCommonLib.IStrings) { 206 | if list.fCombobox.fHandle == 0 { 207 | list.GStringList.AddStrings(strs) 208 | return 209 | } 210 | for i := 0; i < strs.Count(); i++ { 211 | list.Add(strs.Strings(i)) 212 | } 213 | } 214 | 215 | func (list *gComboBoxStrings) IndexOf(str string) int { 216 | if list.fCombobox.fHandle == 0 { 217 | return list.GStringList.IndexOf(str) 218 | } 219 | mp := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(str))) 220 | m := -1 221 | return int(WinApi.SendMessage(list.fCombobox.fHandle, WinApi.CB_FINDSTRINGEXACT, uintptr(m), mp)) 222 | } 223 | 224 | func (list *gComboBoxStrings) AddPair(Name, Value string) { 225 | if list.fCombobox.fHandle == 0 { 226 | list.GStringList.AddPair(Name, Value) 227 | return 228 | } 229 | list.Add(fmt.Sprintf("%s=%s", Name, Value)) 230 | } 231 | 232 | func (lst *gComboBoxStrings) IndexOfName(Name string) int { 233 | if lst.fCombobox.fHandle == 0 { 234 | return lst.GStringList.IndexOfName(Name) 235 | } 236 | for i := 0; i < lst.Count(); i++ { 237 | v := lst.Strings(i) 238 | if eidx := strings.IndexByte(v, '='); eidx > 0 { 239 | bt := []byte(v) 240 | if string(bt[:eidx]) == Name { 241 | return i 242 | } 243 | } 244 | } 245 | return -1 246 | } 247 | 248 | func (lst *gComboBoxStrings) ValueFromIndex(index int) string { 249 | if lst.fCombobox.fHandle == 0 { 250 | return lst.GStringList.ValueFromIndex(index) 251 | } 252 | tc := lst.Count() 253 | if tc == 0 { 254 | return "" 255 | } 256 | if index >= 0 && index < tc { 257 | str := lst.Strings(index) 258 | if idx := strings.IndexByte(str, '='); idx > 0 { 259 | bt := []byte(str) 260 | return DxCommonLib.FastByte2String(bt[idx+1:]) 261 | } 262 | return "" 263 | } 264 | return "" 265 | } 266 | 267 | func (list *gComboBoxStrings) ValueByName(Name string) string { 268 | if list.fCombobox.fHandle == 0 { 269 | return list.GStringList.ValueByName(Name) 270 | } 271 | for i := 0; i < list.Count(); i++ { 272 | v := list.Strings(i) 273 | if eidx := strings.IndexByte(v, '='); eidx > 0 { 274 | bt := []byte(v) 275 | if string(bt[:eidx]) == Name { 276 | return DxCommonLib.FastByte2String(bt[eidx+1:]) 277 | } 278 | } 279 | } 280 | return "" 281 | } 282 | 283 | func (list *gComboBoxStrings) Names(Index int) string { 284 | if list.fCombobox.fHandle == 0 { 285 | return list.GStringList.Names(Index) 286 | } 287 | if list.Count() == 0 { 288 | return "" 289 | } 290 | if Index >= 0 && Index < list.Count() { 291 | str := list.Strings(Index) 292 | if idx := strings.IndexByte(str, '='); idx > 0 { 293 | bt := []byte(str) 294 | return DxCommonLib.FastByte2String(bt[:idx]) 295 | } 296 | return "" 297 | } 298 | return "" 299 | } 300 | 301 | func (list *gComboBoxStrings) AsSlice() []string { 302 | if list.fCombobox.fHandle == 0 { 303 | return list.GStringList.AsSlice() 304 | } 305 | tc := list.Count() 306 | result := make([]string, tc) 307 | for i := 0; i < tc; i++ { 308 | result[i] = list.Strings(i) 309 | } 310 | return result 311 | } 312 | 313 | func (list *gComboBoxStrings) AddSlice(strs []string) { 314 | if list.fCombobox.fHandle == 0 { 315 | list.GStringList.AddSlice(strs) 316 | return 317 | } 318 | for _, str := range strs { 319 | list.Add(str) 320 | } 321 | } 322 | 323 | func (cmbox *GCombobox) GetItemIndex() int { 324 | return int(WinApi.SendMessage(cmbox.fHandle, WinApi.CB_GETCURSEL, 0, 0)) 325 | } 326 | 327 | func (cmbox *GCombobox) SetItemIndex(idx int) { 328 | if cmbox.HandleAllocated() { 329 | if cmbox.GetItemIndex() != idx { 330 | WinApi.SendMessage(cmbox.fHandle, WinApi.CB_GETCURSEL, uintptr(idx), 0) 331 | } 332 | } else { 333 | cmbox.fItemIndex = idx 334 | } 335 | } 336 | 337 | func (cmbox *GCombobox) CreateParams(params *Components.GCreateParams) { 338 | cmbox.GWinControl.CreateParams(params) 339 | cmbox.InitSubclassParams(params, "COMBOBOX") 340 | params.Style = params.Style | (WinApi.WS_VSCROLL | WinApi.CBS_HASSTRINGS | WinApi.CBS_AUTOHSCROLL) 341 | switch cmbox.fStyle { 342 | case CSDropDown: 343 | params.Style = params.Style | WinApi.CBS_DROPDOWN 344 | case CSSimple: 345 | params.Style = params.Style | WinApi.CBS_SIMPLE 346 | case CSDropDownList: 347 | params.Style = params.Style | WinApi.CBS_DROPDOWNLIST 348 | case CSOwnerDrawFixed: 349 | params.Style = params.Style | WinApi.CBS_DROPDOWNLIST | WinApi.CBS_OWNERDRAWFIXED 350 | case CSOwnerDrawVariable: 351 | params.Style = params.Style | WinApi.CBS_DROPDOWNLIST | WinApi.CBS_OWNERDRAWVARIABLE 352 | } 353 | params.WinClassName = "GCombobox" 354 | } 355 | 356 | var ( 357 | cmbListWndprocCallBack = syscall.NewCallback(cmbListWndProc) 358 | cmbEdtWndprocCallBack = syscall.NewCallback(cmbEdtWndProc) 359 | ) 360 | 361 | func cmbListWndProc(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) (result uintptr) { 362 | cmbox := (*GCombobox)(unsafe.Pointer(WinApi.GetProp(hwnd, uintptr(controlAtom)))) 363 | if cmbox == nil { 364 | return WinApi.DefWindowProc(hwnd, msg, wparam, lparam) 365 | } 366 | result = cmbox.comboWndProc(msg, wparam, lparam, hwnd, cmbox.fDefEditProc) 367 | return 368 | } 369 | 370 | func cmbEdtWndProc(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) (result uintptr) { 371 | cmbox := (*GCombobox)(unsafe.Pointer(WinApi.GetProp(hwnd, uintptr(controlAtom)))) 372 | if cmbox == nil { 373 | return WinApi.DefWindowProc(hwnd, msg, wparam, lparam) 374 | } 375 | if msg == WinApi.WM_SYSCOMMAND { 376 | result, _ := cmbox.WndProc(msg, wparam, lparam) 377 | return result 378 | } 379 | result = cmbox.comboWndProc(msg, wparam, lparam, hwnd, cmbox.fDefEditProc) 380 | return 381 | } 382 | 383 | func (cmbox *GCombobox) comboWndProc(msg uint32, wparam, lparam uintptr, msghwnd syscall.Handle, defwndproc uintptr) (result uintptr) { 384 | return WinApi.CallWindowProc(defwndproc, msghwnd, msg, wparam, lparam) 385 | } 386 | 387 | func (cmbox *GCombobox) WndProc(msg uint32, wparam, lparam uintptr) (result uintptr, msgDispatchNext bool) { 388 | result = 0 389 | msgDispatchNext = false 390 | switch msg { 391 | case WinApi.WM_COMMAND: 392 | notifycode := WinApi.HiWord(uint32(wparam)) 393 | switch notifycode { 394 | case WinApi.CBN_DBLCLK: 395 | fmt.Println("Asdf") 396 | case WinApi.CBN_EDITCHANGE: 397 | if cmbox.OnChange != nil { 398 | cmbox.OnChange(cmbox) 399 | } 400 | case WinApi.CBN_SELCHANGE: 401 | index := cmbox.GetItemIndex() 402 | strptr, _ := syscall.UTF16PtrFromString(cmbox.fItems.Strings(index)) 403 | cmbox.Perform(WinApi.WM_SETTEXT, 0, uintptr(unsafe.Pointer(strptr))) 404 | WinApi.SendMessage(cmbox.fHandle, WinApi.CB_SHOWDROPDOWN, 0, 0) 405 | if cmbox.OnSelect != nil { 406 | cmbox.OnSelect(cmbox) 407 | } else if cmbox.OnChange != nil { 408 | cmbox.OnChange(cmbox) 409 | } 410 | case WinApi.CBN_CLOSEUP: 411 | if cmbox.OnCloseUp != nil { 412 | cmbox.OnCloseUp(cmbox) 413 | } 414 | default: 415 | result = WinApi.CallWindowProc(cmbox.FDefWndProc, cmbox.fHandle, msg, wparam, lparam) 416 | } 417 | case WinApi.WM_SETFONT: 418 | result = WinApi.CallWindowProc(cmbox.FDefWndProc, cmbox.fHandle, msg, wparam, lparam) 419 | //设置实际高度 420 | ItemHeight := int32(WinApi.SendMessage(cmbox.fHandle, WinApi.CB_GETITEMHEIGHT, 0, 0)) 421 | WinApi.SetWindowPos(cmbox.fHandle, 0, 0, 0, cmbox.fwidth, ItemHeight*cmbox.fDropDownCount+ 422 | cmbox.fheight+2, WinApi.SWP_NOMOVE|WinApi.SWP_NOZORDER|WinApi.SWP_NOACTIVATE|WinApi.SWP_NOREDRAW| 423 | WinApi.SWP_SHOWWINDOW) 424 | default: 425 | result = WinApi.CallWindowProc(cmbox.FDefWndProc, cmbox.fHandle, msg, wparam, lparam) 426 | } 427 | return 428 | } 429 | 430 | func (cmbox *GCombobox) DroppedDown() bool { 431 | if cmbox.fHandle != 0 { 432 | return WinApi.SendMessage(cmbox.fHandle, WinApi.CB_GETDROPPEDSTATE, 0, 0) != 0 433 | } 434 | return false 435 | } 436 | 437 | func (cmbox *GCombobox) SetDroppedDown(v bool) { 438 | if cmbox.fHandle != 0 { 439 | WinApi.SendMessage(cmbox.fHandle, WinApi.CB_SHOWDROPDOWN, uintptr(DxCommonLib.Ord(v)), 0) 440 | r := cmbox.ClientRect() 441 | WinApi.InvalidateRect(cmbox.fHandle, &r, true) 442 | } 443 | } 444 | 445 | func (cmbox *GCombobox) CreateWindowHandle(params *Components.GCreateParams) bool { 446 | if cmbox.GWinControl.CreateWindowHandle(params) { 447 | for i := 0; i < cmbox.fItems.GStringList.Count(); i++ { 448 | lp := uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(cmbox.fItems.GStringList.Strings(i)))) 449 | WinApi.SendMessage(cmbox.fHandle, WinApi.CB_ADDSTRING, 0, lp) 450 | } 451 | if cmbox.fItemIndex < cmbox.fItems.GStringList.Count() { 452 | WinApi.SendMessage(cmbox.fHandle, WinApi.CB_SETCURSEL, uintptr(cmbox.fItemIndex), 0) 453 | } 454 | cmbox.fItems.GStringList.Clear() 455 | if cmbox.fStyle == CSDropDown || cmbox.fStyle == CSSimple { 456 | if ChildHandle := WinApi.GetWindow(cmbox.fHandle, WinApi.GW_CHILD); ChildHandle != 0 { 457 | if cmbox.fStyle == CSSimple { 458 | cmbox.fListHandle = ChildHandle 459 | WinApi.SetProp(ChildHandle, uintptr(controlAtom), uintptr(unsafe.Pointer(cmbox))) 460 | if DxCommonLib.IsAmd64 { 461 | //指定窗口过程 462 | cmbox.fDefListProc = uintptr(WinApi.SetWindowLongPtr(ChildHandle, WinApi.GWL_WNDPROC, int64(cmbListWndprocCallBack))) 463 | } else { 464 | cmbox.fDefListProc = uintptr(WinApi.SetWindowLong(ChildHandle, WinApi.GWL_WNDPROC, int(cmbListWndprocCallBack))) 465 | } 466 | ChildHandle = WinApi.GetWindow(ChildHandle, WinApi.GW_HWNDNEXT) 467 | } 468 | cmbox.fEditHandle = ChildHandle 469 | WinApi.SetProp(ChildHandle, uintptr(controlAtom), uintptr(unsafe.Pointer(cmbox))) 470 | if DxCommonLib.IsAmd64 { 471 | //指定窗口过程 472 | cmbox.fDefEditProc = uintptr(WinApi.SetWindowLongPtr(ChildHandle, WinApi.GWL_WNDPROC, int64(cmbEdtWndprocCallBack))) 473 | } else { 474 | cmbox.fDefEditProc = uintptr(WinApi.SetWindowLong(ChildHandle, WinApi.GWL_WNDPROC, int(cmbEdtWndprocCallBack))) 475 | } 476 | } 477 | } 478 | return true 479 | } 480 | return false 481 | } 482 | 483 | func (cmbox *GCombobox) Items() DxCommonLib.IStrings { 484 | return cmbox.fItems 485 | } 486 | 487 | func (cmbox *GCombobox) SubInit() { 488 | if cmbox.fItems == nil { 489 | cmbox.fItems = &gComboBoxStrings{fCombobox: cmbox} 490 | } 491 | cmbox.GWinControl.SubInit() 492 | cmbox.GComponent.SubInit(cmbox) 493 | } 494 | 495 | func (cmbox *GCombobox) SetDropDownCount(v int) { 496 | if cmbox.fDropDownCount != int32(v) { 497 | cmbox.fDropDownCount = int32(v) 498 | if cmbox.fHandle != 0 { 499 | ItemHeight := int32(WinApi.SendMessage(cmbox.fHandle, WinApi.CB_GETITEMHEIGHT, 0, 0)) 500 | WinApi.SetWindowPos(cmbox.fHandle, 0, 0, 0, cmbox.fwidth, ItemHeight*cmbox.fDropDownCount+ 501 | cmbox.fheight+2, WinApi.SWP_NOMOVE|WinApi.SWP_NOZORDER|WinApi.SWP_NOACTIVATE|WinApi.SWP_NOREDRAW| 502 | WinApi.SWP_SHOWWINDOW) 503 | } 504 | } 505 | } 506 | 507 | func NewCombobox(aParent Components.IWincontrol, mstyle GComboBoxStyle) *GCombobox { 508 | pType := reflect.TypeOf(aParent) 509 | hasWincontrol := false 510 | if pType.Kind() == reflect.Ptr { 511 | _, hasWincontrol = pType.Elem().FieldByName("GWinControl") 512 | } 513 | if hasWincontrol { 514 | cmb := new(GCombobox) 515 | cmb.SubInit() 516 | cmb.fwidth = 145 517 | cmb.fDropDownCount = 8 518 | cmb.fVisible = true 519 | cmb.fStyle = mstyle 520 | cmb.fheight = 25 521 | cmb.fColor = Graphics.ClWhite 522 | cmb.SetParent(aParent) 523 | return cmb 524 | } 525 | return nil 526 | } 527 | -------------------------------------------------------------------------------- /Components/DxControls/Scintilla/AMD64/SciLexer.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/suiyunonghen/GVCL/7eda51bafb141c506b3f87b18ac6ed91f662ce35/Components/DxControls/Scintilla/AMD64/SciLexer.dll -------------------------------------------------------------------------------- /Components/DxControls/Scintilla/DxHtmlLexer.go: -------------------------------------------------------------------------------- 1 | /* 2 | Scintilla编辑器Html语法高亮分析器 3 | Autor: 不得闲 4 | QQ:75492895 5 | */ 6 | package Scintilla 7 | 8 | import( 9 | "github.com/suiyunonghen/GVCL/Graphics" 10 | ) 11 | const( 12 | SCE_H_DEFAULT = 0 13 | SCE_H_TAG = 1 14 | SCE_H_TAGUNKNOWN = 2 15 | SCE_H_ATTRIBUTE = 3 16 | SCE_H_ATTRIBUTEUNKNOWN = 4 17 | SCE_H_NUMBER = 5 18 | SCE_H_DOUBLESTRING = 6 19 | SCE_H_SINGLESTRING = 7 20 | SCE_H_OTHER = 8 21 | SCE_H_COMMENT = 9 22 | SCE_H_ENTITY = 10 23 | SCE_H_TAGEND = 11 24 | SCE_H_XMLSTART = 12 25 | SCE_H_XMLEND = 13 26 | SCE_H_SCRIPT = 14 27 | SCE_H_ASP = 15 28 | SCE_H_ASPAT = 16 29 | SCE_H_CDATA = 17 30 | SCE_H_QUESTION = 18 31 | SCE_H_VALUE = 19 32 | SCE_H_XCCOMMENT = 20 33 | SCE_H_SGML_DEFAULT = 21 34 | SCE_H_SGML_COMMAND = 22 35 | SCE_H_SGML_1ST_PARAM = 23 36 | SCE_H_SGML_DOUBLESTRING = 24 37 | SCE_H_SGML_SIMPLESTRING = 25 38 | SCE_H_SGML_ERROR = 26 39 | SCE_H_SGML_SPECIAL = 27 40 | SCE_H_SGML_ENTITY = 28 41 | SCE_H_SGML_COMMENT = 29 42 | SCE_H_SGML_1ST_PARAM_COMMENT = 30 43 | SCE_H_SGML_BLOCK_DEFAULT = 31 44 | SCE_HJ_START = 40 45 | SCE_HJ_DEFAULT = 41 46 | SCE_HJ_COMMENT = 42 47 | SCE_HJ_COMMENTLINE = 43 48 | SCE_HJ_COMMENTDOC = 44 49 | SCE_HJ_NUMBER = 45 50 | SCE_HJ_WORD = 46 51 | SCE_HJ_KEYWORD = 47 52 | SCE_HJ_DOUBLESTRING = 48 53 | SCE_HJ_SINGLESTRING = 49 54 | SCE_HJ_SYMBOLS = 50 55 | SCE_HJ_STRINGEOL = 51 56 | SCE_HJ_REGEX = 52 57 | SCE_HJA_START = 55 58 | SCE_HJA_DEFAULT = 56 59 | SCE_HJA_COMMENT = 57 60 | SCE_HJA_COMMENTLINE = 58 61 | SCE_HJA_COMMENTDOC = 59 62 | SCE_HJA_NUMBER = 60 63 | SCE_HJA_WORD = 61 64 | SCE_HJA_KEYWORD = 62 65 | SCE_HJA_DOUBLESTRING = 63 66 | SCE_HJA_SINGLESTRING = 64 67 | SCE_HJA_SYMBOLS = 65 68 | SCE_HJA_STRINGEOL = 66 69 | SCE_HJA_REGEX = 67 70 | SCE_HB_START = 70 71 | SCE_HB_DEFAULT = 71 72 | SCE_HB_COMMENTLINE = 72 73 | SCE_HB_NUMBER = 73 74 | SCE_HB_WORD = 74 75 | SCE_HB_STRING = 75 76 | SCE_HB_IDENTIFIER = 76 77 | SCE_HB_STRINGEOL = 77 78 | SCE_HBA_START = 80 79 | SCE_HBA_DEFAULT = 81 80 | SCE_HBA_COMMENTLINE = 82 81 | SCE_HBA_NUMBER = 83 82 | SCE_HBA_WORD = 84 83 | SCE_HBA_STRING = 85 84 | SCE_HBA_IDENTIFIER = 86 85 | SCE_HBA_STRINGEOL = 87 86 | SCE_HP_START = 90 87 | SCE_HP_DEFAULT = 91 88 | SCE_HP_COMMENTLINE = 92 89 | SCE_HP_NUMBER = 93 90 | SCE_HP_STRING = 94 91 | SCE_HP_CHARACTER = 95 92 | SCE_HP_WORD = 96 93 | SCE_HP_TRIPLE = 97 94 | SCE_HP_TRIPLEDOUBLE = 98 95 | SCE_HP_CLASSNAME = 99 96 | SCE_HP_DEFNAME = 100 97 | SCE_HP_OPERATOR = 101 98 | SCE_HP_IDENTIFIER = 102 99 | SCE_HPHP_COMPLEX_VARIABLE = 104 100 | SCE_HPA_START = 105 101 | SCE_HPA_DEFAULT = 106 102 | SCE_HPA_COMMENTLINE = 107 103 | SCE_HPA_NUMBER = 108 104 | SCE_HPA_STRING = 109 105 | SCE_HPA_CHARACTER = 110 106 | SCE_HPA_WORD = 111 107 | SCE_HPA_TRIPLE = 112 108 | SCE_HPA_TRIPLEDOUBLE = 113 109 | SCE_HPA_CLASSNAME = 114 110 | SCE_HPA_DEFNAME = 115 111 | SCE_HPA_OPERATOR = 116 112 | SCE_HPA_IDENTIFIER = 117 113 | SCE_HPHP_DEFAULT = 118 114 | SCE_HPHP_HSTRING = 119 115 | SCE_HPHP_SIMPLESTRING = 120 116 | SCE_HPHP_WORD = 121 117 | SCE_HPHP_NUMBER = 122 118 | SCE_HPHP_VARIABLE = 123 119 | SCE_HPHP_COMMENT = 124 120 | SCE_HPHP_COMMENTLINE = 125 121 | SCE_HPHP_HSTRING_VARIABLE = 126 122 | SCE_HPHP_OPERATOR = 127 123 | ) 124 | 125 | type ( 126 | GHtmlLexer struct { 127 | fEditor *GScintilla 128 | fHtmlFonts [21]*GDxLexerFont //Html字体设置 SCE_H_DEFAULT---SCE_H_XCCOMMENT 129 | fsgmlFonts [11]*GDxLexerFont //sgml字体设置 SCE_H_SGML_DEFAULT---SCE_H_SGML_ERROR 130 | fJsFonts [13]*GDxLexerFont //JavaScript字体设置 SCE_HJ_START -- SCE_HJ_REGEX ,SCE_HJA_START-- SCE_HJA_REGEX 131 | fVbFonts [8]*GDxLexerFont //VBScript字体设置 SCE_HB_START -- SCE_HB_STRINGEOL ,SCE_HBA_START -- SCE_HBA_STRINGEOL 132 | fPyFonts [13]*GDxLexerFont //Python SCE_HP_START -- SCE_HP_IDENTIFIER , SCE_HPA_START -- SCE_HPA_IDENTIFIER 133 | fPhpFonts [11]*GDxLexerFont //PHP SCE_HPHP_DEFAULT -- SCE_HPHP_COMPLEX_VARIABLE 134 | } 135 | ) 136 | 137 | func (lexer *GHtmlLexer)Editor()*GScintilla { 138 | return lexer.fEditor 139 | } 140 | 141 | func (lexer *GHtmlLexer)Update() { 142 | if lexer.fEditor != nil && lexer.fEditor.HandleAllocated() { 143 | lexer.fEditor.SendEditor(SCI_SETLEXER, SCLEX_HTML, 0) 144 | if lexer.fEditor.MarginBand.ShowCodeFlod { 145 | lexer.fEditor.SetProperty("fold", "1") 146 | lexer.fEditor.SetProperty("fold.compact", "1") 147 | lexer.fEditor.SetProperty("fold.preprocessor", "1") 148 | lexer.fEditor.SetProperty("fold.scriptcomments", "1") 149 | lexer.fEditor.SetProperty("fold.scriptheredocs", "1") 150 | } 151 | //初始化字体信息 152 | for idx := SCE_H_DEFAULT;idx<=SCE_H_XCCOMMENT;idx++{ 153 | lexer.fHtmlFonts[idx-SCE_H_DEFAULT].InitLexFont() 154 | } 155 | for idx := SCE_H_SGML_DEFAULT;idx<=SCE_H_SGML_ERROR;idx++{ 156 | lexer.fsgmlFonts[idx-SCE_H_SGML_DEFAULT].InitLexFont() 157 | } 158 | 159 | for idx := SCE_HJ_START;idx<=SCE_HJ_REGEX;idx++{ 160 | lexer.fJsFonts[idx-SCE_HJ_START].InitLexFont() 161 | } 162 | 163 | for idx := SCE_HB_START;idx<=SCE_HB_STRINGEOL;idx++{ 164 | lexer.fVbFonts[idx-SCE_HB_START].InitLexFont() 165 | } 166 | 167 | for idx := SCE_HP_START;idx<=SCE_HP_IDENTIFIER;idx++{ 168 | lexer.fPyFonts[idx-SCE_HP_START].InitLexFont() 169 | } 170 | 171 | for idx := SCE_HPHP_DEFAULT;idx<=SCE_HPHP_OPERATOR;idx++ { 172 | lexer.fPhpFonts[idx-SCE_HPHP_DEFAULT].InitLexFont() 173 | } 174 | lexer.fEditor.fInitLexer = true 175 | } 176 | } 177 | 178 | func (lexer *GHtmlLexer)SetEditor(scintilla *GScintilla) { 179 | lexer.fEditor = scintilla 180 | } 181 | 182 | func (lexer *GHtmlLexer)Language()string { 183 | return "HTML" 184 | } 185 | 186 | 187 | func (lexer *GHtmlLexer)LexerId()int { 188 | return SCLEX_HTML 189 | } 190 | 191 | func (lexer *GHtmlLexer)KeyWords(keywordIndex int)string { 192 | switch keywordIndex { 193 | case 2://JavaScript关键字 194 | return "abstract boolean break byte case catch char class const continue debugger default delete do double else enum export extends final "+ 195 | "finally float for function goto if implements import in instanceof int interface long native new package private protected public "+ 196 | "return short static super switch synchronized this throw throws transient try typeof var void volatile while with" 197 | case 3://VBScript 198 | return "and begin case call continue do each else elseif end erase error event exit false for function get gosub goto if implement in load loop lset me mid new next "+ 199 | "not nothing on or property raiseevent rem resume return rset select set stop sub then to true unload until wend while with withevents attribute alias as boolean "+ 200 | "byref byte byval const compare currency date declare dim double enum explicit friend global integer let lib long module object option optional preserve private property "+ 201 | "public redim single static string type variant" 202 | case 4: //Python 203 | return "and as assert break class continue def del elif else except exec finally for from global if import in is lambda None not or pass "+ 204 | "print raise return try while with yield" 205 | case 5://PHP 206 | return "and argv as argc break case cfunction class continue declare default do die echo else elseif empty enddeclare endfor endforeach "+ 207 | "endif endswitch endwhile e_all e_parse e_error e_warning eval exit extends false for foreach function global http_cookie_vars http_get_vars http_post_vars "+ 208 | "http_post_files http_env_vars http_server_vars if include include_once list new not null old_function or parent php_os php_self php_version print "+ 209 | "require require_once return static switch stdclass this true var xor virtual while __file__ __line__ __sleep __wakeup" 210 | default: 211 | return "a abbr acronym address applet area b base basefont bdo big blockquote body br button caption center cite code col colgroup "+ 212 | "dd del dfn dir div dl dt em fieldset font form frame frameset h1 h2 h3 h4 h5 h6 head hr html i iframe img input ins isindex kbd "+ 213 | "label legend li link map menu meta noframes noscript object ol optgroup option p param pre q s samp script select small span strike strong style "+ 214 | "sub sup table tbody td textarea tfoot th thead title tr tt u ul var xml xmlns abbr accept-charset accept accesskey action align alink alt archive axis "+ 215 | "background bgcolor border cellpadding cellspacing char charoff charset checked cite class classid clear codebase codetype color cols colspan compact content coords "+ 216 | "data datafld dataformatas datapagesize datasrc datetime declare defer dir disabled enctype event face for frame frameborder headers height href hreflang hspace http-equiv "+ 217 | "id ismap label lang language leftmargin link longdesc marginwidth marginheight maxlength media method multiple name nohref noresize noshade nowrap object onblur onchange onclick ondblclick onfocus "+ 218 | "onkeydown onkeypress onkeyup onload onmousedown onmousemove onmouseover onmouseout onmouseup onreset onselect onsubmit onunload profile prompt readonly rel rev rows rowspan rules "+ 219 | "scheme scope selected shape size span src standby start style summary tabindex target text title topmargin type usemap valign value valuetype version vlink vspace width "+ 220 | "text password checkbox radio submit reset file hidden image public !doctype" 221 | } 222 | } 223 | 224 | 225 | func NewHtmlLexer()*GHtmlLexer { 226 | result := new(GHtmlLexer) 227 | for idx := SCE_H_DEFAULT;idx<=SCE_H_XCCOMMENT;idx++{ 228 | result.fHtmlFonts[idx-SCE_H_DEFAULT] = NewLexerFont(result,idx,0) 229 | if idx == SCE_H_TAG || idx==SCE_H_ATTRIBUTE{ 230 | result.fHtmlFonts[idx].fKeyWordIndex = 1 231 | if idx == SCE_H_TAG{ 232 | result.fHtmlFonts[idx].fColor = Graphics.RGB(128,0,128) 233 | }else{ 234 | result.fHtmlFonts[idx].fColor = Graphics.ClBlack 235 | } 236 | result.fHtmlFonts[idx].fStyle.SetBold(true) 237 | }else{ 238 | switch idx { 239 | case SCE_H_TAGEND: 240 | result.fHtmlFonts[idx].fColor = Graphics.RGB(128,0,128) 241 | case SCE_H_NUMBER: 242 | result.fHtmlFonts[idx].fColor = Graphics.ClBlue 243 | case SCE_H_DOUBLESTRING,SCE_H_SINGLESTRING,SCE_H_VALUE: 244 | result.fHtmlFonts[idx].fColor = Graphics.RGB(59,59,255) 245 | case SCE_H_COMMENT: 246 | result.fHtmlFonts[idx].fColor = Graphics.RGB(59,59,255) 247 | case SCE_H_CDATA: 248 | result.fHtmlFonts[idx].fColor = Graphics.RGB(106,135,89) 249 | case SCE_H_QUESTION: 250 | result.fHtmlFonts[idx].fColor = Graphics.ClRed 251 | } 252 | } 253 | } 254 | for idx := SCE_H_SGML_DEFAULT;idx<=SCE_H_SGML_ERROR;idx++{ 255 | result.fsgmlFonts[idx-SCE_H_SGML_DEFAULT] = NewLexerFont(result,idx,0) 256 | } 257 | 258 | for idx := SCE_HJ_START;idx<=SCE_HJ_REGEX;idx++{ 259 | result.fJsFonts[idx-SCE_HJ_START] = NewLexerFont(result,idx,0) 260 | //SCE_HJA_START 261 | if idx == SCE_HJ_WORD || idx==SCE_HJ_KEYWORD{ 262 | result.fJsFonts[idx-SCE_HJ_START].fKeyWordIndex = 2 263 | //result.fHtmlFonts[idx] 264 | } 265 | } 266 | 267 | for idx := SCE_HB_START;idx<=SCE_HB_STRINGEOL;idx++{ 268 | result.fVbFonts[idx-SCE_HB_START] = NewLexerFont(result,idx,0) 269 | if idx == SCE_HB_WORD{ 270 | result.fVbFonts[idx-SCE_HB_START].fKeyWordIndex = 3 271 | } 272 | } 273 | 274 | for idx := SCE_HP_START;idx<=SCE_HP_IDENTIFIER;idx++{ 275 | result.fPyFonts[idx-SCE_HP_START] = NewLexerFont(result,idx,0) 276 | if idx == SCE_HP_WORD{ 277 | result.fPyFonts[idx-SCE_HP_START].fKeyWordIndex = 4 278 | } 279 | } 280 | 281 | for idx := SCE_HPHP_DEFAULT;idx<=SCE_HPHP_OPERATOR;idx++{ 282 | result.fPhpFonts[idx-SCE_HPHP_DEFAULT] = NewLexerFont(result,idx,0) 283 | if idx == SCE_HPHP_WORD{ 284 | result.fPhpFonts[idx-SCE_HPHP_DEFAULT].fKeyWordIndex = 5 285 | } 286 | } 287 | return result 288 | } -------------------------------------------------------------------------------- /Components/DxControls/Scintilla/DxLanguageLexer.go: -------------------------------------------------------------------------------- 1 | /* 2 | Scintilla编辑器语法分析器包装 3 | Autor: 不得闲 4 | QQ:75492895 5 | */ 6 | package Scintilla 7 | 8 | import ( 9 | "github.com/suiyunonghen/GVCL/Graphics" 10 | "github.com/suiyunonghen/GVCL/WinApi" 11 | "github.com/suiyunonghen/DxCommonLib" 12 | "unsafe" 13 | ) 14 | 15 | type( 16 | //HighlightFont 17 | GDxLexerFont struct { 18 | fCharset byte 19 | fColor Graphics.GColorValue //前景色 20 | fBackColor Graphics.GColorValue //背景色 21 | fStyleNum int //高亮样式 22 | fStyle Graphics.GFontStyles //字体样式 23 | fKeyWords string //高亮关键字 24 | fKeyWordIndex uint8 //所对应的关键字高亮索引 25 | fEditor *GScintilla 26 | fUseEditorBackColor bool //是否使用编辑器背景色 27 | fOwnerLexer ILanguageLexer //属于哪个语法高亮分析器 28 | fKeyWordStyle bool //是否是语法关键字 29 | fName string //字体名称 30 | fSize uint8 31 | OtherStyleNums []int //可以同时兼顾作为其他字体的样式 32 | } 33 | 34 | //高亮词法分析器 35 | ILanguageLexer interface { 36 | Language()string 37 | LexerId()int 38 | KeyWords(keywordIndex int)string 39 | Update() 40 | Editor()*GScintilla 41 | SetEditor(scintilla *GScintilla) 42 | } 43 | 44 | GDxLanguageLexer struct { 45 | fEditor *GScintilla 46 | DefFont GDxLexerFont //默认字体 47 | CommentFont GDxLexerFont //注释字体 48 | KeyWordFont GDxLexerFont //关键字字体 49 | StringFont GDxLexerFont //字符串字体 50 | NumberFont GDxLexerFont //数字字体 51 | OperatorFont GDxLexerFont //操作符字体 52 | } 53 | 54 | GcppLexer struct { 55 | GDxLanguageLexer 56 | 57 | } 58 | 59 | GGoLexer struct { 60 | GcppLexer 61 | } 62 | ) 63 | 64 | func (lexer *GDxLanguageLexer)Editor()*GScintilla { 65 | return lexer.fEditor 66 | } 67 | 68 | func (lexer *GDxLanguageLexer)Update() { 69 | lexer.fEditor.fInitLexer = true 70 | } 71 | 72 | func (lexer *GDxLanguageLexer)SetEditor(scintilla *GScintilla) { 73 | lexer.fEditor = scintilla 74 | } 75 | 76 | func (fnt *GDxLexerFont)Init() { 77 | fnt.fUseEditorBackColor = true 78 | fnt.fCharset = WinApi.DEFAULT_CHARSET 79 | fnt.fBackColor = Graphics.ClWhite 80 | fnt.fColor = Graphics.ClBlack 81 | fnt.fName = "Courier New" 82 | fnt.fSize = 10 83 | fnt.fStyleNum = 0 84 | fnt.fKeyWordIndex = 0 85 | } 86 | 87 | func (lexer *GcppLexer)Language()string { 88 | return "cpp" 89 | } 90 | 91 | 92 | func (lexer *GcppLexer)LexerId()int { 93 | return SCLEX_CPP 94 | } 95 | 96 | func (lexer *GGoLexer)KeyWords(keywordIndex int)string { 97 | return "var const package import func return defer go select interface struct break "+ 98 | "case continue for fallthrough else if switch goto default chan type map range "+ 99 | "uintptr int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 bool float float32 float64" 100 | } 101 | 102 | func (lexer *GGoLexer)Update() { 103 | if lexer.fEditor != nil && lexer.fEditor.HandleAllocated(){ 104 | lexer.fEditor.SendEditor(SCI_SETLEXER,lexer.LexerId(),0) 105 | if lexer.fEditor.MarginBand.ShowCodeFlod{ 106 | lexer.fEditor.SetProperty("fold","1") 107 | lexer.fEditor.SetProperty("fold.compact","0") 108 | } 109 | lexer.DefFont.InitLexFont() 110 | lexer.NumberFont.InitLexFont() 111 | lexer.CommentFont.InitLexFont() 112 | lexer.KeyWordFont.InitLexFont() 113 | lexer.StringFont.InitLexFont() 114 | lexer.OperatorFont.InitLexFont() 115 | lexer.GDxLanguageLexer.Update() 116 | } 117 | } 118 | 119 | 120 | func (lexer *GcppLexer)KeyWords(keywordIndex int)string { 121 | return "and and_eq asm auto bitand bitor bool break case catch char class compl const const_cast continue default delete do double dynamic_cast else enum "+ 122 | "explicit export extern false float for friend goto if inline int long mutable namespace new not not_eq operator or or_eq private protected public register "+ 123 | "reinterpret_cast return short signed sizeof static static_cast struct switch template this throw true try typedef typeid typename union unsigned using "+ 124 | "virtual void volatile wchar_t while xor xor_eq" 125 | } 126 | 127 | func (lexerFont *GDxLexerFont)InitLexFont() { 128 | var editor *GScintilla 129 | if lexerFont.fOwnerLexer != nil{ 130 | editor = lexerFont.fOwnerLexer.Editor() 131 | }else{ 132 | editor = lexerFont.fEditor 133 | } 134 | if editor!=nil{ 135 | if lexerFont.fKeyWordStyle && lexerFont.fKeyWords == ""{ 136 | return 137 | } 138 | var b []byte 139 | if lexerFont.fKeyWordStyle && lexerFont.fKeyWords != ""{ 140 | b = []byte(lexerFont.fKeyWords) 141 | b = append(b,0) 142 | editor.SendEditor(SCI_SETKEYWORDS, int(lexerFont.fKeyWordIndex), int(uintptr(unsafe.Pointer(&b[0])))) 143 | } 144 | if lexerFont.fName != ""{ 145 | b := ([]byte)(lexerFont.fName) 146 | b = append(b,0) 147 | editor.SendEditor(SCI_STYLESETFONT,lexerFont.fStyleNum,int(uintptr(unsafe.Pointer(&b[0])))) 148 | if lexerFont.OtherStyleNums != nil { 149 | for _,style := range lexerFont.OtherStyleNums{ 150 | editor.SendEditor(SCI_STYLESETFONT,style,int(uintptr(unsafe.Pointer(&b[0])))) 151 | } 152 | } 153 | } 154 | if lexerFont.fSize > 0{ 155 | editor.SendEditor(SCI_STYLESETSIZE,lexerFont.fStyleNum,int(lexerFont.fSize)) //大小 156 | if lexerFont.OtherStyleNums != nil { 157 | for _,style := range lexerFont.OtherStyleNums{ 158 | editor.SendEditor(SCI_STYLESETSIZE,style,int(lexerFont.fSize)) //大小 159 | } 160 | } 161 | } 162 | editor.SendEditor(SCI_STYLESETFORE,lexerFont.fStyleNum,int(lexerFont.fColor))//前景 163 | if lexerFont.OtherStyleNums != nil { 164 | for _,style := range lexerFont.OtherStyleNums{ 165 | editor.SendEditor(SCI_STYLESETFORE,style,int(lexerFont.fColor))//前景 166 | } 167 | } 168 | 169 | if lexerFont.fUseEditorBackColor{ 170 | editor.SendEditor(SCI_STYLESETBACK,lexerFont.fStyleNum,int(editor.GetColor())) 171 | if lexerFont.OtherStyleNums != nil { 172 | for _,style := range lexerFont.OtherStyleNums{ 173 | editor.SendEditor(SCI_STYLESETBACK,style,int(editor.GetColor())) 174 | } 175 | } 176 | }else{ 177 | editor.SendEditor(SCI_STYLESETBACK,lexerFont.fStyleNum,int(lexerFont.fBackColor)) 178 | if lexerFont.OtherStyleNums != nil { 179 | for _,style := range lexerFont.OtherStyleNums{ 180 | editor.SendEditor(SCI_STYLESETBACK,style,int(lexerFont.fBackColor)) 181 | } 182 | } 183 | } 184 | boldb,italicb,underlineb,_ := lexerFont.fStyle.StyleInfo() 185 | bold := int(DxCommonLib.Ord(boldb)) 186 | italic := int(DxCommonLib.Ord(italicb)) 187 | underline := int(DxCommonLib.Ord(underlineb)) 188 | editor.SendEditor(SCI_STYLESETBOLD,lexerFont.fStyleNum,bold) 189 | editor.SendEditor(SCI_STYLESETITALIC,lexerFont.fStyleNum,italic) 190 | editor.SendEditor(SCI_STYLESETUNDERLINE,lexerFont.fStyleNum,underline) 191 | editor.SendEditor(SCI_STYLESETCHARACTERSET,lexerFont.fStyleNum,int(lexerFont.fCharset)) 192 | if lexerFont.OtherStyleNums != nil { 193 | for _,style := range lexerFont.OtherStyleNums{ 194 | editor.SendEditor(SCI_STYLESETBOLD,style,bold) 195 | editor.SendEditor(SCI_STYLESETITALIC,style,italic) 196 | editor.SendEditor(SCI_STYLESETUNDERLINE,style,underline) 197 | editor.SendEditor(SCI_STYLESETCHARACTERSET,style,int(lexerFont.fCharset)) 198 | } 199 | } 200 | } 201 | } 202 | 203 | func NewLexerFont(Lexer ILanguageLexer,StyleNum int,KeyWordIndex uint8)(result *GDxLexerFont) { 204 | result = new(GDxLexerFont) 205 | result.Init() 206 | result.fOwnerLexer = Lexer 207 | result.fStyleNum = StyleNum 208 | result.fKeyWordIndex = KeyWordIndex 209 | return result 210 | } 211 | 212 | func NewGoLexer()*GGoLexer { 213 | 214 | result := new(GGoLexer) 215 | 216 | ostyleNums := [9]int{} 217 | result.DefFont.Init() 218 | ostyleNums[8] = SCE_C_IDENTIFIER 219 | result.DefFont.fStyleNum = SCE_C_DEFAULT 220 | result.DefFont.fColor = Graphics.ClBlack 221 | result.DefFont.OtherStyleNums = ostyleNums[8:9] 222 | result.DefFont.fOwnerLexer = result 223 | 224 | result.CommentFont.Init() 225 | result.CommentFont.fOwnerLexer = result 226 | result.CommentFont.fColor = Graphics.RGB(128,128,128) 227 | result.CommentFont.fStyleNum = SCE_C_COMMENT 228 | //所有的注释字体,全部用这个 229 | ostyleNums[0] = SCE_C_COMMENTLINE 230 | ostyleNums[1] = SCE_C_COMMENTDOC 231 | ostyleNums[2] = SCE_C_COMMENTLINEDOC 232 | ostyleNums[3] = SCE_C_COMMENTDOCKEYWORD 233 | ostyleNums[4] = SCE_C_COMMENTDOCKEYWORDERROR 234 | result.CommentFont.OtherStyleNums = ostyleNums[:5] 235 | 236 | 237 | 238 | result.KeyWordFont.Init() 239 | result.KeyWordFont.fColor = Graphics.RGB(62,62,152) 240 | result.KeyWordFont.fOwnerLexer = result 241 | result.KeyWordFont.fStyleNum = SCE_C_WORD 242 | result.KeyWordFont.fKeyWordStyle = true 243 | result.KeyWordFont.fKeyWords = result.KeyWords(0) 244 | ostyleNums[5] = SCE_C_WORD2 245 | result.KeyWordFont.OtherStyleNums = ostyleNums[5:6] 246 | 247 | 248 | result.StringFont.Init() 249 | result.StringFont.fOwnerLexer = result 250 | result.StringFont.fStyleNum = SCE_C_STRING 251 | result.StringFont.fColor = Graphics.RGB(106,135,89) 252 | ostyleNums[6] = SCE_C_STRINGEOL 253 | ostyleNums[7] = SCE_C_CHARACTER 254 | result.StringFont.OtherStyleNums = ostyleNums[6:8] 255 | 256 | 257 | result.NumberFont.Init() 258 | result.NumberFont.fOwnerLexer = result 259 | result.NumberFont.fColor = Graphics.ClBlue 260 | result.NumberFont.fStyleNum = SCE_C_NUMBER 261 | 262 | result.OperatorFont.Init() 263 | result.OperatorFont.fOwnerLexer = result 264 | result.OperatorFont.fStyleNum = SCE_C_OPERATOR 265 | return result 266 | } -------------------------------------------------------------------------------- /Components/DxControls/Scintilla/MarginBand.go: -------------------------------------------------------------------------------- 1 | /* 2 | Scintilla编辑器控件的Margin封装 3 | Autor: 不得闲 4 | QQ:75492895 5 | */ 6 | package Scintilla 7 | 8 | import( 9 | "github.com/suiyunonghen/GVCL/Graphics" 10 | "github.com/suiyunonghen/DxCommonLib" 11 | "unsafe" 12 | "fmt" 13 | ) 14 | 15 | type ( 16 | //边条单击事件 17 | GMarginClick func(sender *GDxMarginBand,pos int,MarginIndex int,modifiers int) 18 | //编辑器边条 19 | GDxMarginBand struct { 20 | fcodeEditor *GScintilla 21 | ShowLineNum bool //是否显示行号 22 | ShowCodeFlod bool //是否代码折叠 23 | TextMargin bool //是否显示文字边 24 | fBookmarks [10]int //保存书签句柄,只保存10个 25 | ShowBookMark bool //是否显示书签 26 | fCodeFlodInited bool //折叠初始化 27 | fLineNumIndex byte //行边索引 28 | fTextIndex byte //文字边索引 29 | fFoldIndex byte //折叠边索引 30 | fBookmarkIndex byte 31 | Color Graphics.GColorValue //边条颜色 32 | OnClick GMarginClick //单击事件 33 | OnRightClick GMarginClick //右键单击 34 | fupcount int 35 | TextMarginWidth int //文字边宽度 36 | BookMarkBack Graphics.GColorValue 37 | BookMarkFont Graphics.GFont 38 | fBookMarkStyle int //书签的文字样式,默认指定254 39 | LineNumFont Graphics.GFont 40 | } 41 | ) 42 | 43 | func (band *GDxMarginBand)BeginUpdate() { 44 | band.fupcount++ 45 | } 46 | 47 | func (band *GDxMarginBand)EndUpdate() { 48 | band.fupcount-- 49 | if band.fupcount<=0{ 50 | band.fupcount=0 51 | band.Update() 52 | } 53 | } 54 | 55 | func (band *GDxMarginBand)ClearMarks() { 56 | if band.fcodeEditor == nil || !band.fcodeEditor.HandleAllocated(){ 57 | return 58 | } 59 | band.fcodeEditor.SendEditor(SCI_MARKERDELETEALL,-1,0) 60 | band.fcodeEditor.SendEditor(SCI_MARGINTEXTCLEARALL,0,0) //清空所有标记 61 | for i := 0;i<10;i++{ 62 | band.fBookmarks[i] = -1 63 | } 64 | } 65 | 66 | func (band *GDxMarginBand)GotoBookmark(bkindex int) { 67 | if band.fcodeEditor == nil || !band.fcodeEditor.HandleAllocated(){ 68 | return 69 | } 70 | band.fcodeEditor.GoToLine(band.fBookmarks[bkindex]) 71 | } 72 | 73 | func (band *GDxMarginBand)UpdateBookMark() { 74 | //指定书签的显示样式 75 | if band.ShowBookMark{ 76 | bold,italic,underline,_ := band.BookMarkFont.FontStyle().StyleInfo() 77 | b := ([]byte)(band.BookMarkFont.FontName) 78 | b = append(b,0) 79 | band.fcodeEditor.SendEditor(SCI_STYLESETFONT,band.fBookMarkStyle,int(uintptr(unsafe.Pointer(&b[0])))) 80 | band.fcodeEditor.SendEditor(SCI_STYLESETITALIC,band.fBookMarkStyle,int(DxCommonLib.Ord(italic))) 81 | band.fcodeEditor.SendEditor(SCI_STYLESETBOLD,band.fBookMarkStyle,int(DxCommonLib.Ord(bold))) 82 | band.fcodeEditor.SendEditor(SCI_STYLESETUNDERLINE,band.fBookMarkStyle,int(DxCommonLib.Ord(underline))) 83 | band.fcodeEditor.SendEditor(SCI_STYLESETFORE,band.fBookMarkStyle,int(band.BookMarkFont.Color)) 84 | band.fcodeEditor.SendEditor(SCI_STYLESETBACK,band.fBookMarkStyle,int(band.BookMarkBack)) 85 | } 86 | if band.ShowLineNum{ 87 | bold,italic,underline,_ := band.LineNumFont.FontStyle().StyleInfo() 88 | b := ([]byte)(band.LineNumFont.FontName) 89 | b = append(b,0) 90 | 91 | band.fcodeEditor.SendEditor(SCI_STYLESETFONT,STYLE_LINENUMBER,int(uintptr(unsafe.Pointer(&b[0])))) 92 | band.fcodeEditor.SendEditor(SCI_STYLESETITALIC,STYLE_LINENUMBER,int(DxCommonLib.Ord(italic))) 93 | band.fcodeEditor.SendEditor(SCI_STYLESETBOLD,STYLE_LINENUMBER,int(DxCommonLib.Ord(bold))) 94 | band.fcodeEditor.SendEditor(SCI_STYLESETUNDERLINE,STYLE_LINENUMBER,int(DxCommonLib.Ord(underline))) 95 | band.fcodeEditor.SendEditor(SCI_STYLESETFORE,STYLE_LINENUMBER,int(band.LineNumFont.Color)) 96 | //band.fcodeEditor.SendEditor(SCI_STYLESETBACK,STYLE_LINENUMBER,int(band.BookMarkBack)) 97 | } 98 | } 99 | 100 | func (band *GDxMarginBand)SetBookmark(bkindex int) { 101 | if band.fcodeEditor == nil || !band.fcodeEditor.HandleAllocated(){ 102 | return 103 | } 104 | if band.fBookmarks[bkindex] != -1{ 105 | band.fcodeEditor.SendEditor(SCI_MARGINSETTEXT,band.fBookmarks[bkindex],0) 106 | } 107 | bt := DxCommonLib.FastString2Byte(fmt.Sprintf("%d",bkindex)) 108 | band.fcodeEditor.SendEditor(SCI_MARGINSETTEXT,band.fcodeEditor.CaretPos.Line,int(uintptr(unsafe.Pointer(&bt[0])))) 109 | band.fcodeEditor.SendEditor(SCI_MARGINSETSTYLE,band.fcodeEditor.CaretPos.Line,band.fBookMarkStyle) //设置书签样式 110 | band.fBookmarks[bkindex] = band.fcodeEditor.CaretPos.Line 111 | } 112 | 113 | func (band *GDxMarginBand)Update() { 114 | if band.fcodeEditor == nil || !band.fcodeEditor.HandleAllocated(){ 115 | return 116 | } 117 | band.fcodeEditor.SendEditor(SCI_STYLESETBACK,33, int(band.Color)) //设置页边颜色 118 | //0号位置行号,1号位置是书签,2号位置文字页边,3号位置折叠 119 | var idx byte = 0 120 | if band.ShowLineNum { 121 | band.fLineNumIndex = 0 122 | idx++ 123 | }else{ 124 | band.fLineNumIndex = 10 125 | } 126 | if band.ShowBookMark{ 127 | band.fBookmarkIndex = idx 128 | idx++ 129 | }else{ 130 | band.fBookmarkIndex = 10 131 | } 132 | if band.TextMargin && band.TextMarginWidth > 8{ 133 | band.fTextIndex = idx 134 | idx++ 135 | }else{ 136 | band.fTextIndex = 10 137 | } 138 | if band.ShowCodeFlod{ 139 | band.fFoldIndex = idx 140 | idx++ 141 | }else{ 142 | band.fFoldIndex = 10 143 | } 144 | //设置页边个数 145 | band.fcodeEditor.SendEditor(SCI_SETMARGINS,int(idx),0) 146 | if band.ShowLineNum{//行号 147 | band.fcodeEditor.SendEditor(SCI_SETMARGINTYPEN,int(band.fLineNumIndex), SC_MARGIN_NUMBER) 148 | str := fmt.Sprintf("_%d",band.fcodeEditor.CodeLines.Count()) 149 | band.fcodeEditor.SendEditor(SCI_SETMARGINWIDTHN,int(band.fLineNumIndex), band.MarginTextLen(str)) //页边长度 150 | if band.ShowBookMark{ 151 | band.fcodeEditor.SendEditor(SCI_SETMARGINCURSORN,int(band.fLineNumIndex), SC_CURSORARROW) 152 | band.fcodeEditor.SendEditor(SCI_SETMARGINSENSITIVEN,int(band.fLineNumIndex),1) //接受鼠标点击 153 | }else{ 154 | band.fcodeEditor.SendEditor(SCI_SETMARGINCURSORN,int(band.fLineNumIndex), SC_CURSORREVERSEARROW) 155 | } 156 | } 157 | 158 | if band.ShowBookMark{ 159 | band.fcodeEditor.SendEditor(SCI_SETMARGINTYPEN,int(band.fBookmarkIndex), SC_MARGIN_TEXT) //文字边距 160 | band.fcodeEditor.SendEditor(SCI_SETMARGINWIDTHN,int(band.fBookmarkIndex), 16) 161 | //这个是0-9位显示,其他的不显示,$03FF设定显示掩码 162 | band.fcodeEditor.SendEditor(SCI_SETMARGINMASKN, int(band.fBookmarkIndex), 0x3FF) 163 | band.fcodeEditor.SendEditor(SCI_SETMARGINSENSITIVEN,int(band.fBookmarkIndex),1); //接受鼠标点击 164 | band.fcodeEditor.SendEditor(SCI_SETMARGINCURSORN,int(band.fBookmarkIndex), SC_CURSORARROW) 165 | 166 | band.UpdateBookMark() 167 | } 168 | 169 | if band.TextMargin{ 170 | band.fcodeEditor.SendEditor(SCI_SETMARGINTYPEN,int(band.fTextIndex), SC_MARGIN_TEXT) //文字边距 171 | band.fcodeEditor.SendEditor(SCI_SETMARGINWIDTHN,int(band.fTextIndex), band.TextMarginWidth) //页边长度 172 | } 173 | 174 | //代码折叠 175 | if band.ShowCodeFlod{ 176 | c := uint(SC_MASK_FOLDERS) 177 | band.fcodeEditor.SendEditor(SCI_SETMARGINTYPEN, int(band.fFoldIndex), SC_MARGIN_SYMBOL) 178 | band.fcodeEditor.SendEditor(SCI_SETMARGINMASKN, int(band.fFoldIndex), int(c)) 179 | band.fcodeEditor.SendEditor(SCI_SETMARGINWIDTHN, int(band.fFoldIndex), 11) //页宽 180 | band.fcodeEditor.SendEditor(SCI_SETMARGINSENSITIVEN, int(band.fFoldIndex), 1) 181 | band.fcodeEditor.SendEditor(SCI_SETMARGINCURSORN,int(band.fFoldIndex), SC_CURSORARROW) 182 | if !band.fCodeFlodInited{ 183 | band.fCodeFlodInited = true 184 | band.fcodeEditor.SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDER, SC_MARK_CIRCLEPLUS); 185 | band.fcodeEditor.SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPEN, SC_MARK_CIRCLEMINUS); 186 | band.fcodeEditor.SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDEREND, SC_MARK_CIRCLEPLUSCONNECTED); 187 | band.fcodeEditor.SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDEROPENMID, SC_MARK_CIRCLEMINUSCONNECTED); 188 | band.fcodeEditor.SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERMIDTAIL, SC_MARK_TCORNERCURVE); 189 | band.fcodeEditor.SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERSUB, SC_MARK_VLINE); 190 | band.fcodeEditor.SendEditor(SCI_MARKERDEFINE, SC_MARKNUM_FOLDERTAIL, SC_MARK_LCORNERCURVE); 191 | 192 | band.fcodeEditor.SendEditor(SCI_SETFOLDFLAGS, 16 | 4, 0) //如果折叠就在折叠行的上下各画一条横线 193 | band.fcodeEditor.SendEditor(SCI_MARKERSETBACK, SC_MARKNUM_FOLDERSUB, 0xa0a0a0) 194 | band.fcodeEditor.SendEditor(SCI_MARKERSETBACK, SC_MARKNUM_FOLDERMIDTAIL, 0xa0a0a0) 195 | band.fcodeEditor.SendEditor(SCI_MARKERSETBACK, SC_MARKNUM_FOLDERTAIL, 0xa0a0a0) 196 | if band.fcodeEditor.fInitLexer{ 197 | band.fcodeEditor.SetProperty("fold","1") 198 | //band.fcodeEditor.SetProperty("fold.compact","0") 199 | band.fcodeEditor.SetProperty("fold.comment","1") 200 | band.fcodeEditor.SetProperty("fold.preprocessor","1") 201 | } 202 | } 203 | }else{ 204 | band.fcodeEditor.SetProperty("fold","0") 205 | band.fcodeEditor.SendEditor(SCI_SETMARGINSENSITIVEN, 2, 0)//去掉鼠标事件 206 | } 207 | 208 | 209 | } 210 | 211 | func (band *GDxMarginBand)MarginTextLen(text string)int { 212 | if band.fcodeEditor != nil && text != "" { 213 | bt := DxCommonLib.FastString2Byte(text) 214 | return band.fcodeEditor.SendEditor(SCI_TEXTWIDTH,STYLE_LINENUMBER,int(uintptr(unsafe.Pointer(&bt[0])))) 215 | }else{ 216 | return 4 217 | } 218 | } 219 | 220 | func (band *GDxMarginBand)FindValidBookmark(ClickLine int)(CurBookmark int,result int) { 221 | result = -1 222 | CurBookmark = -1 223 | for i := 0;i<10;i++{ 224 | if band.fBookmarks[i] == -1{ 225 | if result == -1{ 226 | result = i 227 | } 228 | }else { 229 | bt := [1]byte{16} 230 | if band.fcodeEditor.SendEditor(SCI_MARGINGETTEXT,ClickLine,int(uintptr(unsafe.Pointer(&bt[0])))) > 0{ 231 | CurBookmark = int(bt[0]) -48 232 | } 233 | } 234 | } 235 | return 236 | } 237 | 238 | func (band *GDxMarginBand)BandClick(pos,MarginIndex,modifiers int) { 239 | lineNumber := band.fcodeEditor.SendEditor(SCI_LINEFROMPOSITION,pos,0) 240 | if MarginIndex == int(band.fBookmarkIndex) || MarginIndex == int(band.fLineNumIndex){ 241 | if band.ShowBookMark{ 242 | //先判断ClickLine有没有书签 243 | var bt []byte 244 | CurBookmark,ValidBkIndex := band.FindValidBookmark(lineNumber) 245 | if CurBookmark == -1{ 246 | //没有书签,加入书签 247 | if ValidBkIndex == -1{ 248 | //然后将0位置的标签去掉 249 | band.fcodeEditor.SendEditor(SCI_MARGINSETTEXT,band.fBookmarks[0],0) 250 | ValidBkIndex = 0 251 | } 252 | bt = DxCommonLib.FastString2Byte(fmt.Sprintf("%d",ValidBkIndex)) 253 | band.fcodeEditor.SendEditor(SCI_MARGINSETTEXT,lineNumber,int(uintptr(unsafe.Pointer(&bt[0])))) 254 | band.fcodeEditor.SendEditor(SCI_MARGINSETSTYLE,lineNumber,band.fBookMarkStyle) //设置书签样式 255 | band.fBookmarks[ValidBkIndex] = lineNumber 256 | }else{ 257 | //移除书签 258 | band.fcodeEditor.SendEditor(SCI_MARGINSETTEXT,lineNumber,0) 259 | band.fBookmarks[CurBookmark] = -1 260 | } 261 | } 262 | }else if MarginIndex == int(band.fFoldIndex){ 263 | band.fcodeEditor.SendEditor(SCI_TOGGLEFOLD, lineNumber,0) 264 | } 265 | } 266 | 267 | func newMarginBand(codeEditor *GScintilla)*GDxMarginBand { 268 | result := new(GDxMarginBand) 269 | result.ShowLineNum = true 270 | result.fBookmarks = [10]int{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} 271 | result.ShowBookMark = true 272 | result.Color = Graphics.ClBtnFace 273 | result.fcodeEditor = codeEditor 274 | result.fBookMarkStyle = STYLE_MAX - 1 275 | result.BookMarkFont.Color = Graphics.RGB(43,43,43) 276 | result.BookMarkBack = Graphics.RGB(169,183,198) 277 | result.BookMarkFont.FontName = "宋体" 278 | result.BookMarkFont.SetSize(9) 279 | result.BookMarkFont.SetBold(true) 280 | 281 | result.LineNumFont.Color = Graphics.RGB(43,43,43) 282 | result.LineNumFont.FontName = "宋体" 283 | result.LineNumFont.SetSize(9) 284 | result.LineNumFont.Color = Graphics.ClRed 285 | result.LineNumFont.SetBold(false) 286 | return result 287 | } 288 | -------------------------------------------------------------------------------- /Components/DxControls/Scintilla/X86/SciLexer.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/suiyunonghen/GVCL/7eda51bafb141c506b3f87b18ac6ed91f662ce35/Components/DxControls/Scintilla/X86/SciLexer.dll -------------------------------------------------------------------------------- /Components/DxControls/WindowLessControls/DxCheckBox.go: -------------------------------------------------------------------------------- 1 | package WindowLessControls 2 | 3 | import ( 4 | "github.com/suiyunonghen/GVCL/WinApi" 5 | "github.com/suiyunonghen/GVCL/Graphics" 6 | "github.com/suiyunonghen/GVCL/Components/Controls" 7 | "github.com/suiyunonghen/GVCL/Components" 8 | "reflect" 9 | ) 10 | 11 | type GDxCheckBox struct { 12 | controls.GBaseControl 13 | fCaption string 14 | fAutoSize bool 15 | fChecked bool 16 | fIsMouseIn bool 17 | fisMouseDown bool 18 | fWordWrap bool 19 | OnChange Graphics.NotifyEvent 20 | } 21 | 22 | func (checkbox *GDxCheckBox) SubInit() { 23 | checkbox.GBaseControl.SubInit() 24 | checkbox.GComponent.SubInit(checkbox) 25 | checkbox.SetTrasparent(true) 26 | checkbox.SetWidth(100) 27 | checkbox.SetHeight(20) 28 | } 29 | 30 | 31 | func (checkbox *GDxCheckBox)calcSize() { 32 | cvs := Graphics.NewCanvas() 33 | fhandle := checkbox.GetTargetCanvas(cvs) 34 | if fhandle == 0{ 35 | return 36 | } 37 | sz := new(WinApi.GSize) 38 | oldr := new(WinApi.Rect) 39 | cvs.RefreshCanvasState() 40 | oldr.Right = checkbox.Width() 41 | oldr.Bottom = checkbox.Height() 42 | cvs.Font().Assign(&checkbox.Font) 43 | if cvs.TextExtent(checkbox.fCaption,sz){ 44 | checkbox.SetWidth(sz.CX + 18); //加上选择区域 45 | if sz.CY < 16{ 46 | sz.CY = 16 47 | } 48 | if oldr.Right < sz.CX{ 49 | oldr.Right = sz.CX 50 | } 51 | if oldr.Bottom < sz.CY{ 52 | oldr.Bottom = sz.CY 53 | } 54 | if oldr.Right != sz.CX || oldr.Bottom != sz.CY{ 55 | oldr.OffsetRect(int(checkbox.Left()),int(checkbox.Top())) 56 | if fhandle != 0{ 57 | WinApi.InvalidateRect(fhandle,oldr,false) 58 | } 59 | } 60 | } 61 | dc := cvs.GetHandle() 62 | cvs.SetHandle(0) 63 | WinApi.ReleaseDC(fhandle,dc) 64 | cvs.Destroy() 65 | } 66 | 67 | func (checkbox *GDxCheckBox)SetAutoSize(v bool) { 68 | if checkbox.fAutoSize != v{ 69 | checkbox.fAutoSize = v 70 | if checkbox.fAutoSize{ 71 | if pc := checkbox.GetParent();pc!=nil && pc.HandleAllocated(){ 72 | checkbox.calcSize() 73 | } 74 | } 75 | } 76 | } 77 | 78 | func (checkbox *GDxCheckBox)AfterParentWndCreate() { 79 | if checkbox.fAutoSize{ 80 | checkbox.calcSize() 81 | } 82 | } 83 | 84 | 85 | func (checkbox *GDxCheckBox)SetCaption(cap string) { 86 | if checkbox.fCaption != cap{ 87 | checkbox.fCaption = cap 88 | if checkbox.fAutoSize{ 89 | checkbox.calcSize() 90 | } 91 | } 92 | } 93 | 94 | func (checkBox *GDxCheckBox)SetChecked(v bool) { 95 | if checkBox.fChecked != v{ 96 | checkBox.fChecked = v 97 | checkBox.Invalidate() 98 | if checkBox.OnChange!=nil{ 99 | checkBox.OnChange(checkBox) 100 | } 101 | } 102 | } 103 | 104 | func (checkbox *GDxCheckBox)Checked()bool { 105 | return checkbox.fChecked 106 | } 107 | 108 | func (checkbox *GDxCheckBox)Paint(cvs Graphics.ICanvas) { 109 | //先绘制checkBox 110 | //居中绘制,大小14*14 111 | if !checkbox.Trasparent(){ 112 | r := WinApi.Rect{0,0,checkbox.Width(),checkbox.Height()} 113 | cvs.FillRect(&r) 114 | } 115 | brush := cvs.Brush() 116 | checkRect := WinApi.Rect{0,0,14,14} 117 | checkRect.Top = (checkbox.Height() - checkRect.Bottom) / 2 118 | checkRect.Bottom = checkRect.Top + 14 119 | if checkbox.fChecked{ 120 | brush.BeginUpdate() 121 | if checkbox.fIsMouseIn{ 122 | if checkbox.fisMouseDown{ 123 | brush.Color = Graphics.RGB(56,140,245) 124 | }else{ 125 | brush.Color = Graphics.RGB(69,165,255) 126 | } 127 | }else{ 128 | brush.Color = Graphics.RGB(66,149,252) 129 | } 130 | brush.EndUpdate() 131 | cvs.FillRect(&checkRect) 132 | //绘制勾选的 133 | pen := cvs.Pen() 134 | pen.Color = Graphics.ClWhite 135 | pen.Change() 136 | cvs.MoveTo(checkRect.Left + 3,checkRect.Top+7) 137 | cvs.LineTo(int(checkRect.Left) + 5,int(checkRect.Top)+9) 138 | cvs.LineTo(int(checkRect.Left) + 11,int(checkRect.Top)+3) 139 | if checkbox.fIsMouseIn{ 140 | if checkbox.fisMouseDown{ 141 | pen.Color = Graphics.RGB(118,176,248) //阴影 142 | }else{ 143 | pen.Color = Graphics.RGB(127,193,255) //阴影 144 | } 145 | }else{ 146 | pen.Color = Graphics.RGB(125,182,253) //阴影 147 | } 148 | pen.Change() 149 | cvs.MoveTo(checkRect.Left + 3,checkRect.Top+8) 150 | cvs.LineTo(int(checkRect.Left) + 5,int(checkRect.Top)+10) 151 | cvs.LineTo(int(checkRect.Left) + 11,int(checkRect.Top)+4) 152 | 153 | if checkbox.fIsMouseIn { 154 | if checkbox.fisMouseDown{ 155 | pen.Color = Graphics.RGB(102,166,247) //阴影 156 | }else { 157 | pen.Color = Graphics.RGB(112, 185, 255) 158 | } 159 | }else{ 160 | pen.Color = Graphics.RGB(109, 173, 252) 161 | } 162 | pen.Change() 163 | 164 | cvs.MoveTo(checkRect.Left,checkRect.Top) 165 | cvs.LineTo(int(checkRect.Left),int(checkRect.Top+1)) 166 | 167 | cvs.MoveTo(checkRect.Left,checkRect.Bottom-1) 168 | cvs.LineTo(int(checkRect.Left+1),int(checkRect.Bottom-1)) 169 | 170 | cvs.MoveTo(checkRect.Right - 1,checkRect.Top) 171 | cvs.LineTo(int(checkRect.Right),int(checkRect.Top)) 172 | 173 | cvs.MoveTo(checkRect.Right - 1,checkRect.Bottom-1) 174 | cvs.LineTo(int(checkRect.Right),int(checkRect.Bottom-1)) 175 | 176 | }else if checkbox.fIsMouseIn{ 177 | brush.BeginUpdate() 178 | brush.Color = Graphics.RGB(66,149,252) 179 | brush.EndUpdate() 180 | cvs.FrameRect(&checkRect) 181 | }else{ 182 | brush.BeginUpdate() 183 | brush.Color = Graphics.RGB(200,206,210) 184 | brush.EndUpdate() 185 | cvs.FrameRect(&checkRect) 186 | } 187 | //绘制Caption 188 | if checkbox.fCaption != ""{ 189 | checkRect.Left = checkRect.Left + 17 190 | checkRect.Top = 0 191 | checkRect.Bottom = checkbox.Height() 192 | checkRect.Right = checkbox.Width() 193 | brush := cvs.Brush() 194 | brush.BrushStyle = Graphics.BSClear 195 | brush.Change() 196 | var drawflags uint = WinApi.DT_LEFT | WinApi.DT_TOP | WinApi.DT_CALCRECT 197 | if checkbox.fWordWrap{ 198 | drawflags = WinApi.DT_LEFT | WinApi.DT_VCENTER | WinApi.DT_WORDBREAK 199 | }else{ 200 | drawflags = WinApi.DT_LEFT | WinApi.DT_VCENTER | WinApi.DT_SINGLELINE 201 | } 202 | WinApi.DrawText(cvs.GetHandle(),checkbox.fCaption,-1,&checkRect,drawflags) 203 | } 204 | 205 | } 206 | 207 | 208 | func (checkbox *GDxCheckBox)MouseDown(button Components.MouseButton,x,y int,state Components.KeyState)bool { 209 | checkbox.fisMouseDown = button == Components.MbLeft 210 | if checkbox.fisMouseDown{ 211 | checkbox.Invalidate() 212 | } 213 | return true 214 | } 215 | 216 | func (checkbox *GDxCheckBox)MouseUp(button Components.MouseButton,x,y int,state Components.KeyState)bool { 217 | if checkbox.fisMouseDown{ 218 | checkbox.fisMouseDown = false 219 | checkbox.fChecked = !checkbox.fChecked 220 | checkbox.Invalidate() 221 | if checkbox.OnChange!=nil{ 222 | checkbox.OnChange(checkbox) 223 | } 224 | } 225 | return true 226 | } 227 | 228 | 229 | 230 | 231 | func (checkbox *GDxCheckBox)MouseEnter(){ 232 | checkbox.fIsMouseIn = true 233 | if checkbox.Enabled(){ 234 | checkbox.Invalidate() 235 | } 236 | checkbox.GBaseControl.MouseEnter() 237 | } 238 | 239 | func (checkbox *GDxCheckBox)MouseLeave(){ 240 | checkbox.fIsMouseIn = false 241 | if checkbox.Enabled(){ 242 | checkbox.Invalidate() 243 | } 244 | checkbox.GBaseControl.MouseLeave() 245 | } 246 | 247 | func NewCheckBox(aParent Components.IWincontrol) *GDxCheckBox { 248 | pType := reflect.TypeOf(aParent) 249 | hasWincontrol := false 250 | if pType.Kind() == reflect.Ptr { 251 | _, hasWincontrol = pType.Elem().FieldByName("GWinControl") 252 | } 253 | if hasWincontrol { 254 | checkbox := new(GDxCheckBox) 255 | checkbox.SubInit() 256 | checkbox.SetParent(aParent) 257 | return checkbox 258 | } 259 | return nil 260 | } -------------------------------------------------------------------------------- /Components/DxControls/WindowLessControls/DxImage.go: -------------------------------------------------------------------------------- 1 | package WindowLessControls 2 | 3 | import ( 4 | "github.com/suiyunonghen/GVCL/Components/Controls" 5 | "github.com/suiyunonghen/GVCL/Graphics" 6 | "github.com/suiyunonghen/GVCL/Components" 7 | "reflect" 8 | "github.com/suiyunonghen/GVCL/WinApi" 9 | ) 10 | 11 | type GDxImage struct { 12 | controls.GBaseControl 13 | fCaption string 14 | Picture Graphics.GBitmap 15 | fDrawStyle Graphics.GDrawStyle 16 | OnChange Graphics.NotifyEvent 17 | } 18 | 19 | func (img *GDxImage)picChange(sender interface{}) { 20 | img.Invalidate() 21 | } 22 | 23 | func (img *GDxImage) SubInit() { 24 | img.GBaseControl.SubInit() 25 | img.GComponent.SubInit(img) 26 | img.SetTrasparent(true) 27 | img.SetWidth(300) 28 | img.SetHeight(300) 29 | img.fDrawStyle = Graphics.GDS_NORMAL 30 | img.Picture.OnChange = img.picChange 31 | } 32 | 33 | func (img *GDxImage)Paint(cvs Graphics.ICanvas) { 34 | w,h := img.Picture.Size() 35 | if w > 0 && h > 0{ 36 | switch img.fDrawStyle { 37 | case Graphics.GDS_NORMAL: 38 | cvs.Draw(0,0,&img.Picture) 39 | case Graphics.GDS_CENTER: 40 | cvs.Draw((int(img.Width()) - w) /2,(int(img.Height()) - h)/2,&img.Picture) 41 | case Graphics.GDS_STRETCH: 42 | srcrect := WinApi.Rect{0,0,int32(w),int32(h)} 43 | destRect := WinApi.Rect{0,0,img.Width(),img.Height()} 44 | img.Picture.DrawToDest(srcrect,destRect,cvs.GetHandle()) 45 | case Graphics.GDS_FILL: 46 | dc := cvs.GetHandle() 47 | srcdc := img.Picture.Canvas().GetHandle() 48 | starty := 0 49 | cwidth := int(img.Width()) 50 | for starty < int(img.Height()){ 51 | startx := 0 52 | for startx < cwidth{ 53 | WinApi.BitBlt(dc,startx,starty,startx+w,starty+h,srcdc,0,0,WinApi.SRCCOPY) 54 | startx += w 55 | } 56 | starty += h 57 | } 58 | } 59 | } 60 | 61 | } 62 | 63 | func (img *GDxImage)AfterParentWndCreate(){ 64 | 65 | } 66 | 67 | func NewImage(aParent Components.IWincontrol,drawStyle Graphics.GDrawStyle) *GDxImage { 68 | pType := reflect.TypeOf(aParent) 69 | hasWincontrol := false 70 | if pType.Kind() == reflect.Ptr { 71 | _, hasWincontrol = pType.Elem().FieldByName("GWinControl") 72 | } 73 | if hasWincontrol { 74 | img := new(GDxImage) 75 | img.SubInit() 76 | img.fDrawStyle = drawStyle 77 | img.SetParent(aParent) 78 | return img 79 | } 80 | return nil 81 | } -------------------------------------------------------------------------------- /Components/DxControls/gminiblink/dll64/node.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/suiyunonghen/GVCL/7eda51bafb141c506b3f87b18ac6ed91f662ce35/Components/DxControls/gminiblink/dll64/node.dll -------------------------------------------------------------------------------- /Components/DxControls/gminiblink/mb_test.go: -------------------------------------------------------------------------------- 1 | package gminiblink 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "testing" 7 | ) 8 | 9 | func TestMiniBlinkLib_JsArg(t *testing.T) { 10 | fmt.Println(strings.Split("test.mm.bb",".")) 11 | fmt.Println(strings.Split("test",".")) 12 | BlinkLib.LoadBlink(`E:\Delphi\Controls\UI\DxSkinctrl\miniblink-190630\node.dll`) 13 | fmt.Println(BlinkLib.VersionString()) 14 | fmt.Println("start") 15 | wkstring := BlinkLib.WkeCreateString("测试不得闲") 16 | fmt.Println(BlinkLib.WkeGetString(wkstring)) 17 | BlinkLib.WkeSetStringW(wkstring,"高价收电费") 18 | fmt.Println(BlinkLib.WkeGetString(wkstring)) 19 | BlinkLib.WkeDeleteString(wkstring) 20 | } -------------------------------------------------------------------------------- /Components/DxControls/gminiblink/miniblikBrowser.go: -------------------------------------------------------------------------------- 1 | package gminiblink 2 | 3 | import ( 4 | "github.com/suiyunonghen/GVCL/Components" 5 | "github.com/suiyunonghen/GVCL/Components/Controls" 6 | "github.com/suiyunonghen/GVCL/Graphics" 7 | "github.com/suiyunonghen/GVCL/WinApi" 8 | "reflect" 9 | "strings" 10 | "unsafe" 11 | ) 12 | 13 | type JSBindHandle func(params ...interface{})interface{} 14 | type JSBindFunction struct { 15 | ParamCount int 16 | BindHandle JSBindHandle 17 | } 18 | 19 | type WebConsoleEvent func(webView WkeWebView, level WkeConsoleLevel, msg, sourceName string, sourceline uint32, stackTrace string) 20 | 21 | type GBlinkWebBrowser struct { 22 | controls.GWinControl 23 | fbindfunctions map[string]*JSBindFunction 24 | fDirectWeb bool 25 | webView WkeWebView 26 | OnConsole WebConsoleEvent 27 | OnDocumentCompleted Graphics.NotifyEvent 28 | 29 | } 30 | 31 | func (webBrowser *GBlinkWebBrowser) SubInit() { 32 | webBrowser.GWinControl.SubInit() 33 | webBrowser.GComponent.SubInit(webBrowser) 34 | } 35 | 36 | func (webBrowser *GBlinkWebBrowser) CreateParams(params *Components.GCreateParams) { 37 | webBrowser.GWinControl.CreateParams(params) 38 | params.WinClassName = "GBlinkWebBrowser" 39 | params.Style = (params.Style | uint32(WinApi.WS_CLIPCHILDREN) & ^(uint32(WinApi.CS_HREDRAW) | uint32(WinApi.CS_VREDRAW))) 40 | } 41 | 42 | func wrapBindFuncs(es JSExecState, param uintptr) JSValue{ 43 | bindFunc := (*JSBindFunction)(unsafe.Pointer(param)) 44 | paramCount := BlinkLib.JsArgCount(es) 45 | params := make([]interface{},paramCount) 46 | for i := 0;i= r.X && p.X <= r.Right() && p.Y >= r.Y && p.Y <= r.Bottom() 26 | } 27 | 28 | func WinRect2WkeRect(r *WinApi.Rect) WkeRect { 29 | return WkeRect{r.Left, r.Top, r.Width(), r.Height()} 30 | } 31 | 32 | type WkePoint struct { 33 | X, Y int32 34 | } 35 | 36 | func (p *WkePoint) ToWinPoint() *WinApi.POINT { 37 | return (*WinApi.POINT)(unsafe.Pointer(p)) 38 | } 39 | 40 | type WKEMouseFlags byte 41 | 42 | const ( 43 | WKE_LBUTTON WKEMouseFlags = 0x01 44 | WKE_RBUTTON WKEMouseFlags = 0x02 45 | WKE_SHIFT WKEMouseFlags = 0x04 46 | WKE_CONTROL WKEMouseFlags = 0x08 47 | WKE_MBUTTON WKEMouseFlags = 0x10 48 | ) 49 | 50 | type WKEKeyFlags uint32 51 | 52 | const ( 53 | WKE_EXTENDED WKEKeyFlags = 0x0100 54 | WKE_REPEAT = 0x4000 55 | ) 56 | 57 | type WKEMouseMsg uint32 58 | 59 | const ( 60 | WKE_MSG_MOUSEMOVE WKEMouseMsg = 0x0200 61 | WKE_MSG_LBUTTONDOWN = 0x0201 62 | WKE_MSG_LBUTTONUP = 0x0202 63 | WKE_MSG_LBUTTONDBLCLK = 0x0203 64 | WKE_MSG_RBUTTONDOWN = 0x0204 65 | WKE_MSG_RBUTTONUP = 0x0205 66 | WKE_MSG_RBUTTONDBLCLK = 0x0206 67 | WKE_MSG_MBUTTONDOWN = 0x0207 68 | WKE_MSG_MBUTTONUP = 0x0208 69 | WKE_MSG_MBUTTONDBLCLK = 0x0209 70 | WKE_MSG_MOUSEWHEEL = 0x020A 71 | ) 72 | 73 | //通过wkeGetCursorInfoType获得光标信息 74 | type WkeCursorInfoType byte 75 | 76 | const ( 77 | WkeCursorInfoPointer WkeCursorInfoType = iota 78 | WkeCursorInfoCross 79 | WkeCursorInfoHand 80 | WkeCursorInfoIBeam 81 | WkeCursorInfoWait 82 | WkeCursorInfoHelp 83 | WkeCursorInfoEastResize 84 | WkeCursorInfoNorthResize 85 | WkeCursorInfoNorthEastResize 86 | WkeCursorInfoNorthWestResize 87 | WkeCursorInfoSouthResize 88 | WkeCursorInfoSouthEastResize 89 | WkeCursorInfoSouthWestResize 90 | WkeCursorInfoWestResize 91 | WkeCursorInfoNorthSouthResize 92 | WkeCursorInfoEastWestResize 93 | WkeCursorInfoNorthEastSouthWestResize 94 | WkeCursorInfoNorthWestSouthEastResize 95 | WkeCursorInfoColumnResize 96 | WkeCursorInfoRowResize 97 | WkeCursorInfoMiddlePanning 98 | WkeCursorInfoEastPanning 99 | WkeCursorInfoNorthPanning 100 | WkeCursorInfoNorthEastPanning 101 | WkeCursorInfoNorthWestPanning 102 | WkeCursorInfoSouthPanning 103 | WkeCursorInfoSouthEastPanning 104 | WkeCursorInfoSouthWestPanning 105 | WkeCursorInfoWestPanning 106 | WkeCursorInfoMove 107 | WkeCursorInfoVerticalText 108 | WkeCursorInfoCell 109 | WkeCursorInfoContextMenu 110 | WkeCursorInfoAlias 111 | WkeCursorInfoProgress 112 | WkeCursorInfoNoDrop 113 | WkeCursorInfoCopy 114 | WkeCursorInfoNone 115 | WkeCursorInfoNotAllowed 116 | WkeCursorInfoZoomIn 117 | WkeCursorInfoZoomOut 118 | WkeCursorInfoGrab 119 | WkeCursorInfoGrabbing 120 | WkeCursorInfoCustom 121 | ) 122 | 123 | type ( 124 | JSExecState uintptr 125 | JSValue int64 126 | PJSValue *JSValue 127 | WkeWebView uintptr 128 | WkeString uintptr 129 | WkeUrlRequestCallbacks struct { 130 | willRedirectCallback uintptr 131 | didReceiveResponseCallback uintptr 132 | didReceiveDataCallback uintptr 133 | didFailCallback uintptr 134 | didFinishLoadingCallback uintptr 135 | } 136 | 137 | WkeWebFrameHandle uintptr 138 | WkeFrameHwnd uintptr 139 | WkeCookieCommand byte 140 | WkeNavigationType byte 141 | WkeConsoleLevel byte 142 | WkeWindowType byte 143 | WkeProxyType byte 144 | ) 145 | 146 | const ( 147 | wkeCookieCommandClearAllCookies WkeCookieCommand = iota 148 | wkeCookieCommandClearSessionCookies 149 | wkeCookieCommandFlushCookiesToFile 150 | wkeCookieCommandReloadCookiesFromFile 151 | ) 152 | 153 | const ( 154 | WKE_NAVIGATION_TYPE_LINKCLICK WkeNavigationType = iota //点击a标签触发 155 | WKE_NAVIGATION_TYPE_FORMSUBMITTE //点击form触发 156 | WKE_NAVIGATION_TYPE_BACKFORWARD //前进后退触发 157 | WKE_NAVIGATION_TYPE_RELOAD //重新加载触发 158 | WKE_NAVIGATION_TYPE_FORMRESUBMITT 159 | WKE_NAVIGATION_TYPE_OTHER 160 | ) 161 | 162 | const ( 163 | WkeLevelDebug WkeConsoleLevel = 4 164 | WkeLevelLog WkeConsoleLevel = 1 165 | WkeLevelInfo WkeConsoleLevel = 5 166 | WkeLevelWarning WkeConsoleLevel = 2 167 | WkeLevelError WkeConsoleLevel = 3 168 | WkeLevelRevokedError WkeConsoleLevel = 6 169 | WkeLevelLast WkeConsoleLevel = WkeLevelInfo 170 | ) 171 | 172 | const ( 173 | WKE_WINDOW_TYPE_POPUP WkeWindowType = iota 174 | WKE_WINDOW_TYPE_TRANSPARENT 175 | WKE_WINDOW_TYPE_CONTROL 176 | ) 177 | 178 | const ( 179 | WKE_PROXY_NONE WkeProxyType = iota 180 | WKE_PROXY_HTTP 181 | WKE_PROXY_SOCKS4 182 | WKE_PROXY_SOCKS4A 183 | WKE_PROXY_SOCKS5 184 | WKE_PROXY_SOCKS5HOSTNAME 185 | ) 186 | 187 | type ( 188 | WkeProxy struct { 189 | Type WkeProxyType 190 | HostName [100]byte 191 | Port uint16 192 | UserName [50]byte 193 | PassWord [50]byte 194 | } 195 | 196 | WkeSettings struct { 197 | Proxy WkeProxy 198 | Mask uint32 199 | } 200 | 201 | WkeViewSettings struct { 202 | Size int32 203 | BackColor uint32 204 | } 205 | 206 | WkeMemBuf struct { 207 | Size int32 208 | Data uintptr 209 | Len uint 210 | } 211 | 212 | WkeWindowFeatures struct { 213 | X, Y, W, H int32 214 | MenuBarVisible bool 215 | StatusBarVisible bool 216 | ToolBarVisible bool 217 | LocationBarVisible bool 218 | ScrollBarVisible bool 219 | Resizeable bool 220 | FullScreen bool 221 | } 222 | 223 | WkeMediaLoadInfo struct { 224 | Size, W, H int32 225 | Duration float64 226 | } 227 | 228 | WkeRequestType byte 229 | WkeHttBodyElementType byte 230 | ) 231 | 232 | const ( 233 | kWkeRequestTypeInvalidation WkeRequestType = iota 234 | kWkeRequestTypeGet 235 | kWkeRequestTypePost 236 | kWkeRequestTypePut 237 | ) 238 | 239 | const ( 240 | wkeHttBodyElementTypeData WkeHttBodyElementType = iota 241 | wkeHttBodyElementTypeFile 242 | ) 243 | 244 | type ( 245 | WkePostBodyElement struct { 246 | Size int32 247 | EType WkeHttBodyElementType 248 | Data *WkeMemBuf 249 | FilePath WkeString 250 | FileStart int64 251 | FileLength int64 252 | } 253 | 254 | WkePostBodyElements struct { 255 | Size int32 256 | Element **WkePostBodyElement 257 | ElementSize uint 258 | IsDirty bool 259 | } 260 | JSType byte 261 | ) 262 | 263 | const ( 264 | JSTYPE_NUMBER JSType = iota 265 | JSTYPE_STRING 266 | JSTYPE_BOOLEAN 267 | JSTYPE_OBJECT 268 | JSTYPE_FUNCTION 269 | JSTYPE_UNDEFINED 270 | JSTYPE_ARRAY 271 | JSTYPE_NULL 272 | ) 273 | 274 | type ( 275 | JsKeys struct { 276 | Len uint16 277 | Keys uintptr 278 | } 279 | 280 | JSData struct { 281 | TypeName [100]byte 282 | PropertyGet uintptr 283 | PropertySet uintptr 284 | Finalize uintptr 285 | CallAsFunction uintptr 286 | TargetData uintptr 287 | } 288 | 289 | JsExceptionInfo struct { 290 | Msg uintptr 291 | SourceLine uintptr 292 | scriptResourceName uintptr 293 | LineNumber int 294 | StartPosition int 295 | EndPosition int 296 | StartColumn int 297 | EndColumn int 298 | CallStackString uintptr 299 | } 300 | WkeLoadingResult byte 301 | WkeSettingMask byte 302 | ) 303 | 304 | const ( 305 | WKE_LOADING_SUCCEEDED WkeLoadingResult = iota 306 | WKE_LOADING_FAILED 307 | WKE_LOADING_CANCELED 308 | ) 309 | 310 | const ( 311 | WKE_SETTING_PROXY WkeSettingMask = 1 312 | WKE_SETTING_PAINTCALLBACK_IN_OTHER_THREAD WkeSettingMask = 1 << 2 313 | ) 314 | 315 | func GetMouseFlags(mouseKeys uint16) uint32 { 316 | result := uint32(0) 317 | if mouseKeys&WinApi.MK_SHIFT != 0 { 318 | result = uint32(WKE_SHIFT) 319 | } 320 | if mouseKeys&WinApi.MK_CONTROL != 0 { 321 | result = result | uint32(WKE_CONTROL) 322 | } 323 | if mouseKeys&WinApi.MK_LBUTTON != 0 { 324 | result = result | uint32(WKE_LBUTTON) 325 | } 326 | 327 | if mouseKeys&WinApi.MK_RBUTTON != 0 { 328 | result = result | uint32(WKE_RBUTTON) 329 | } 330 | if mouseKeys&WinApi.MK_MBUTTON != 0 { 331 | result = result | uint32(WKE_MBUTTON) 332 | } 333 | return result 334 | } 335 | -------------------------------------------------------------------------------- /Components/DxControls/gminiblink/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Components/NVisbleControls/menus.go: -------------------------------------------------------------------------------- 1 | package NVisbleControls 2 | 3 | import ( 4 | "github.com/suiyunonghen/GVCL/WinApi" 5 | "github.com/suiyunonghen/GVCL/Graphics" 6 | "github.com/suiyunonghen/GVCL/Components" 7 | "fmt" 8 | "syscall" 9 | "unsafe" 10 | ) 11 | 12 | type IMenu interface { 13 | IsPopupMenu()bool 14 | MenuHandle()WinApi.HMENU 15 | } 16 | 17 | type GPopList struct { 18 | WindowHandle syscall.Handle 19 | usedIds []*GMenuItem 20 | } 21 | 22 | func (popList *GPopList)MenuItemById(Id uint16)*GMenuItem { 23 | if popList.usedIds != nil && Id>0 && int(Id)<=len(popList.usedIds){ 24 | return popList.usedIds[Id - 1] 25 | } 26 | return nil 27 | } 28 | 29 | func (popList *GPopList)setItemMenuId(item *GMenuItem) { 30 | if popList.usedIds == nil{ 31 | popList.usedIds = make([]*GMenuItem,256) 32 | popList.usedIds[0] = item 33 | item.fMenuId = 1 34 | return 35 | } 36 | totallen := len(popList.usedIds) 37 | for i:=0;i0 && id <= uint16(len(popList.usedIds)){ 51 | popList.usedIds[id-1] = nil 52 | } 53 | } 54 | var( 55 | PopList *GPopList 56 | ) 57 | 58 | type GMenu struct { 59 | Components.GComponent 60 | fItems *GMenuItem 61 | } 62 | 63 | func (menu *GMenu)Destroy(){ 64 | if menu.fItems != nil{ 65 | menu.fItems.Destroy() 66 | } 67 | } 68 | 69 | func (menu *GMenu)CreateMenu() { 70 | if menu.fItems==nil{ 71 | menu.fItems = new(GMenuItem) 72 | menu.fItems.SubInit() 73 | var targeobj interface{} 74 | if i := menu.SubChildCount() -1;i>=0{ 75 | targeobj = menu.SubChild(i) 76 | }else{ 77 | targeobj = menu 78 | } 79 | menu.fItems.fOwnerMenu = targeobj 80 | } 81 | if menu.fItems.GetHandle() == 0{ 82 | panic(fmt.Sprintf("创建菜单失败,错误代码:%d",WinApi.GetLastError())) 83 | } 84 | } 85 | 86 | func (menu *GMenu)MenuHandle()WinApi.HMENU { 87 | return menu.fItems.GetHandle() 88 | } 89 | 90 | func (menu *GMenu)IsPopupMenu()bool { 91 | var targeobj interface{} 92 | if i := menu.SubChildCount() -1;i>=0{ 93 | targeobj = menu.SubChild(i) 94 | return targeobj.(IMenu).IsPopupMenu() 95 | } 96 | return false 97 | } 98 | 99 | func (menu *GMenu)SubInit() { 100 | menu.GObject.SubInit(menu) 101 | } 102 | 103 | type GPopupMenu struct { 104 | GMenu 105 | } 106 | 107 | func (menu *GPopupMenu)IsPopupMenu()bool { 108 | return true 109 | } 110 | 111 | func (menu *GPopupMenu)SubInit() { 112 | menu.GMenu.SubInit() 113 | menu.GObject.SubInit(menu) 114 | } 115 | 116 | func (menu *GPopupMenu)PopUp(x,y int32) { 117 | MenuHandle := menu.MenuHandle() 118 | if MenuHandle!=0{ 119 | WinApi.TrackPopupMenu(MenuHandle,WinApi.TPM_LEFTALIGN,int(x),int(y),0,PopList.WindowHandle,nil) 120 | } 121 | } 122 | 123 | func (menu *GPopupMenu)CloseMenu(){ 124 | WinApi.EndMenu() 125 | } 126 | 127 | func (menu *GPopupMenu)Items()*GMenuItem { 128 | if menu.fItems == nil{ 129 | menu.fItems = new(GMenuItem) 130 | menu.fItems.SubInit() 131 | var targeobj interface{} 132 | if i := menu.SubChildCount() -1;i>=0{ 133 | targeobj = menu.SubChild(i) 134 | }else{ 135 | targeobj = menu 136 | } 137 | menu.fItems.fOwnerMenu = targeobj 138 | } 139 | return menu.fItems 140 | } 141 | 142 | //菜单项目 143 | type GMenuItem struct { 144 | Graphics.GObject 145 | menuHandle WinApi.HMENU 146 | fownerItem *GMenuItem 147 | fCaption string 148 | fEnabled bool 149 | fDefault bool 150 | fOwnerMenu interface{} 151 | fitemList []*GMenuItem 152 | fIndex int32 153 | fMenuId uint16 154 | fChecked bool 155 | OnClick Graphics.NotifyEvent 156 | } 157 | 158 | func (item *GMenuItem)Click() { 159 | if item.OnClick!=nil{ 160 | item.OnClick(item) 161 | } 162 | } 163 | 164 | func (item *GMenuItem)Caption() string { 165 | return item.fCaption 166 | } 167 | 168 | func NewMenuItem(menucaption string)*GMenuItem { 169 | menuitem := new(GMenuItem) 170 | menuitem.SubInit() 171 | menuitem.fCaption = menucaption 172 | return menuitem 173 | } 174 | 175 | func (citem *GMenuItem)appendToParentItem(parentItem *GMenuItem) { 176 | PopList.setItemMenuId(citem) 177 | itemInfo := new(WinApi.GMenuItemInfo) 178 | itemInfo.CbSize = uint32(unsafe.Sizeof(*itemInfo)) 179 | itemInfo.FMask = WinApi.MIIM_CHECKMARKS | WinApi.MIIM_DATA | WinApi.MIIM_ID | 180 | WinApi.MIIM_STATE | WinApi.MIIM_SUBMENU | WinApi.MIIM_TYPE 181 | itemInfo.WID = uint32(citem.fMenuId) 182 | var fstate uint32 183 | if citem.fChecked { 184 | fstate= WinApi.MFS_CHECKED 185 | }else{ 186 | fstate= WinApi.MFS_UNCHECKED 187 | } 188 | if citem.fEnabled{ 189 | fstate = fstate | WinApi.MFS_ENABLED 190 | }else{ 191 | fstate = fstate | WinApi.MFS_DISABLED 192 | } 193 | if citem.fDefault{ 194 | fstate = fstate | WinApi.MFS_DEFAULT 195 | } 196 | itemInfo.FState = fstate 197 | if citem.fCaption == "-"{ 198 | fstate = WinApi.MFT_SEPARATOR 199 | }else{ 200 | fstate =WinApi.MFT_STRING 201 | } 202 | itemInfo.DwTypeData = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(citem.fCaption))) 203 | itemInfo.FType = fstate 204 | if citem.fitemList !=nil && len(citem.fitemList)>0 { 205 | itemInfo.HSubMenu = citem.GetHandle() 206 | if itemInfo.HSubMenu == 0{ 207 | panic(fmt.Sprintf("创建菜单失败,错误代码:%d",WinApi.GetLastError())) 208 | } 209 | }else{ 210 | itemInfo.HSubMenu = 0 211 | } 212 | WinApi.InsertMenuItem(parentItem.menuHandle,0xFFFFFFFF,true,itemInfo) 213 | } 214 | 215 | func (item *GMenuItem)AddItem(caption string)(menuitem *GMenuItem) { 216 | menuitem = new(GMenuItem) 217 | if item.fitemList == nil{ 218 | item.fitemList = make([]*GMenuItem,0) 219 | } 220 | menuitem.SubInit() 221 | menuitem.fIndex = int32(len(item.fitemList)) 222 | menuitem.fOwnerMenu= nil 223 | menuitem.fCaption = caption 224 | menuitem.fownerItem = item 225 | item.fitemList = append(item.fitemList,menuitem) 226 | if item.menuHandle != 0{ 227 | if menuitem.fMenuId == 0{ 228 | PopList.setItemMenuId(menuitem) 229 | } 230 | menuitem.appendToParentItem(item) 231 | } 232 | return 233 | } 234 | 235 | 236 | func (item *GMenuItem)SetEnabled(v bool) { 237 | if item.fEnabled != v{ 238 | item.fEnabled = v 239 | if item.fownerItem != nil && item.fownerItem.menuHandle != 0{ 240 | WinApi.EnableMenuItem(item.fownerItem.menuHandle,int(item.fIndex),v) 241 | } 242 | } 243 | } 244 | 245 | 246 | func (item *GMenuItem)prepareItems() { 247 | if item.fitemList == nil { 248 | return 249 | } 250 | itemInfo := new(WinApi.GMenuItemInfo) 251 | itemInfo.CbSize = uint32(unsafe.Sizeof(*itemInfo)) 252 | itemInfo.FMask = WinApi.MIIM_CHECKMARKS | WinApi.MIIM_DATA | WinApi.MIIM_ID | 253 | WinApi.MIIM_STATE | WinApi.MIIM_SUBMENU | WinApi.MIIM_TYPE 254 | var fstate uint32 255 | if itemlen := len(item.fitemList); itemlen >0{ 256 | for i := 0;i0 { 284 | itemInfo.HSubMenu = subitem.GetHandle() 285 | if itemInfo.HSubMenu == 0{ 286 | panic(fmt.Sprintf("创建菜单失败,错误代码:%d",WinApi.GetLastError())) 287 | } 288 | }else{ 289 | itemInfo.HSubMenu = 0 290 | } 291 | WinApi.InsertMenuItem(item.menuHandle,0xFFFFFFFF,true,itemInfo) 292 | } 293 | } 294 | } 295 | 296 | func (item *GMenuItem)SubInit() { 297 | item.GObject.SubInit(item) 298 | item.fEnabled = true 299 | item.fChecked = false 300 | item.fDefault = false 301 | } 302 | 303 | func (item *GMenuItem)Destroy() { 304 | if item.fitemList != nil{ //回收菜单ID 305 | for _,v := range item.fitemList { 306 | PopList.reciveMenuId(v.fMenuId) 307 | } 308 | } 309 | if item.menuHandle != 0{ 310 | WinApi.DestroyMenu(item.menuHandle) 311 | item.menuHandle = 0 312 | } 313 | } 314 | 315 | func (item *GMenuItem)GetHandle()WinApi.HMENU { 316 | if item.menuHandle== 0{ 317 | if item.fOwnerMenu != nil && item.fOwnerMenu.(IMenu).IsPopupMenu(){ 318 | item.menuHandle = WinApi.CreatePopupMenu() 319 | }else{ 320 | item.menuHandle = WinApi.CreateMenu() 321 | } 322 | //填充菜单 323 | item.prepareItems() 324 | } 325 | return item.menuHandle 326 | } 327 | 328 | func NewPopupMenu(Owner interface{})*GPopupMenu { 329 | popmenu := new(GPopupMenu) 330 | popmenu.SubInit() 331 | popmenu.SetOwner(Owner) 332 | return popmenu 333 | } 334 | -------------------------------------------------------------------------------- /Components/NVisbleControls/registry.go: -------------------------------------------------------------------------------- 1 | package NVisbleControls 2 | 3 | import ( 4 | "github.com/suiyunonghen/GVCL/WinApi" 5 | "github.com/suiyunonghen/GVCL/Graphics" 6 | "strings" 7 | "syscall" 8 | "unsafe" 9 | ) 10 | 11 | type GRegKeyInfo struct { 12 | NumSubKeys uint32 13 | MaxSubKeyLen uint32 14 | NumValues uint32 15 | MaxValueLen uint32 16 | MaxDataLen uint32 17 | FileTime WinApi.GFileTime 18 | } 19 | type GRegistry struct { 20 | Graphics.GObject 21 | fCurrentKey WinApi.HKEY 22 | fRootKey WinApi.HKEY 23 | fLazyWrite bool 24 | fCurrentPath string 25 | fCloseRootKey bool 26 | fAccess uint32 27 | fLastError int32 28 | } 29 | 30 | type GRegDataType byte 31 | const ( 32 | _ GRegDataType=iota 33 | RdUnknown=iota 34 | RdString 35 | RdExpandString 36 | RdInteger 37 | RdBinary 38 | ) 39 | 40 | type GRegDataInfo struct { 41 | RegData GRegDataType 42 | DataSize uint32 43 | } 44 | 45 | func (registry *GRegistry) SubInit() { 46 | registry.GObject.SubInit(registry) 47 | registry.SetRootKey(WinApi.HKEY_CURRENT_USER) 48 | registry.fAccess = WinApi.KEY_ALL_ACCESS 49 | registry.fLazyWrite = true 50 | } 51 | func (registry *GRegistry)Destroy() { 52 | registry.CloseKey() 53 | } 54 | 55 | func (reg *GRegistry)SetRootKey(rkey WinApi.HKEY) { 56 | if reg.fRootKey != rkey{ 57 | if reg.fCloseRootKey{ 58 | WinApi.RegCloseKey(reg.fRootKey); 59 | reg.fCloseRootKey = false 60 | } 61 | reg.fRootKey = rkey 62 | reg.CloseKey() 63 | } 64 | } 65 | 66 | func (reg *GRegistry)CloseKey() { 67 | if reg.fCurrentKey != 0{ 68 | if !reg.fLazyWrite{ 69 | WinApi.RegFlushKey(reg.fCurrentKey) 70 | } 71 | WinApi.RegCloseKey(reg.fCurrentKey) 72 | reg.fCurrentKey = 0 73 | reg.fCurrentPath = "" 74 | } 75 | } 76 | 77 | func (reg *GRegistry)CurrentKey()WinApi.HKEY { 78 | return reg.fCurrentKey 79 | } 80 | 81 | func (reg *GRegistry)CheckResult(RetVal int32)bool { 82 | reg.fLastError = RetVal 83 | return RetVal == WinApi.ERROR_SUCCESS 84 | } 85 | 86 | func (reg *GRegistry)getBaseKey(Relative bool)WinApi.HKEY { 87 | if reg.fCurrentKey == 0 || !Relative{ 88 | return reg.fRootKey 89 | }else{ 90 | return reg.fCurrentKey 91 | } 92 | } 93 | 94 | func (reg *GRegistry)ChangeKey(Value WinApi.HKEY,Path string) { 95 | reg.CloseKey() 96 | reg.fCurrentKey = Value 97 | reg.fCurrentPath = Path 98 | } 99 | 100 | func (reg *GRegistry)OpenKey(keypath string,Cancreate bool)(result bool) { 101 | Relative := !(keypath != "" && keypath[0]==92) 102 | if !Relative{ 103 | keypath = strings.Trim(keypath,"\\") 104 | } 105 | var TempKey WinApi.HKEY = 0 106 | if !Cancreate || keypath == ""{ 107 | result = reg.CheckResult(WinApi.RegOpenKeyEx(reg.getBaseKey(Relative), WinApi.PChar(keypath), 0, 108 | WinApi.REGSAM(reg.fAccess), &TempKey)) 109 | }else{ 110 | var lpdwDisposition uint32=0 111 | result = reg.CheckResult(WinApi.RegCreateKeyEx(reg.getBaseKey(Relative), WinApi.PChar(keypath), 0, nil, 112 | WinApi.REG_OPTION_NON_VOLATILE, WinApi.REGSAM(reg.fAccess), nil, &TempKey, &lpdwDisposition)) 113 | } 114 | if result{ 115 | if reg.fCurrentKey != 0 && Relative{ 116 | keypath = reg.fCurrentPath + "\\" + keypath; 117 | } 118 | reg.ChangeKey(TempKey, keypath) 119 | } 120 | return 121 | } 122 | 123 | func (reg *GRegistry)CreateKey(Key string)bool { 124 | Relative := !(Key != "" && Key[0]==92) 125 | if !Relative{ 126 | Key = strings.Trim(Key,"\\") 127 | } 128 | var TempKey WinApi.HKEY = 0 129 | WOWFlags := reg.fAccess & WinApi.KEY_WOW64_RES 130 | var lpdwDisposition uint32=0 131 | result := reg.CheckResult(WinApi.RegCreateKeyEx(reg.getBaseKey(Relative), WinApi.PChar(Key), 0, nil, 132 | WinApi.REG_OPTION_NON_VOLATILE, WinApi.REGSAM(WinApi.KEY_ALL_ACCESS | WOWFlags), nil, &TempKey, &lpdwDisposition)) 133 | if result{ 134 | WinApi.RegCloseKey(TempKey) 135 | } 136 | return result 137 | } 138 | 139 | func (reg *GRegistry)getKey(key string)(Result WinApi.HKEY) { 140 | Relative := !(key != "" && key[0]==92) 141 | if !Relative{ 142 | key = strings.Trim(key,"\\") 143 | } 144 | Result = 0 145 | WinApi.RegOpenKeyEx(reg.getBaseKey(Relative), WinApi.PChar(key), 0, WinApi.REGSAM(reg.fAccess), &Result) 146 | return Result 147 | } 148 | 149 | func (reg *GRegistry)getKeyInfo()(keyinfo *GRegKeyInfo,ok bool) { 150 | keyinfo = new(GRegKeyInfo) 151 | ok = reg.CheckResult(WinApi.RegQueryInfoKey(reg.fCurrentKey, nil, nil, 0, &keyinfo.NumSubKeys, 152 | &keyinfo.MaxSubKeyLen, nil, &keyinfo.NumValues, &keyinfo.MaxValueLen, 153 | &keyinfo.MaxDataLen, nil, &keyinfo.FileTime)) 154 | if ok{ 155 | keyinfo.MaxSubKeyLen += keyinfo.MaxSubKeyLen 156 | keyinfo.MaxValueLen += keyinfo.MaxValueLen 157 | } 158 | return 159 | } 160 | 161 | func (reg *GRegistry)DeleteKey(Key string)bool { 162 | Relative := !(Key != "" && Key[0]==92) 163 | if !Relative{ 164 | Key = strings.Trim(Key,"\\") 165 | } 166 | OldKey := reg.fCurrentKey 167 | fDeleteKey := reg.getKey(Key) 168 | if fDeleteKey != 0{ 169 | reg.fCurrentKey = fDeleteKey 170 | if keyinfo,ok := reg.getKeyInfo();ok{ 171 | KeyName := make([]uint16,keyinfo.MaxSubKeyLen+1) 172 | for i := keyinfo.NumSubKeys - 1;i>=0;i--{ 173 | Len := keyinfo.MaxSubKeyLen + 1 174 | if reg.CheckResult(WinApi.RegEnumKeyEx(fDeleteKey, uint(i), &KeyName[0], &Len, 0, nil, nil, nil)){ 175 | reg.DeleteKey(syscall.UTF16ToString(KeyName)) 176 | } 177 | } 178 | } 179 | reg.fCurrentKey = OldKey 180 | WinApi.RegCloseKey(fDeleteKey) 181 | } 182 | if WinApi.RegDeleteKeyEx != nil{ 183 | return reg.CheckResult(WinApi.RegDeleteKeyEx(reg.getBaseKey(Relative), WinApi.PChar(Key), WinApi.REGSAM(reg.fAccess & WinApi.KEY_WOW64_RES), 0)) 184 | } 185 | return reg.CheckResult(WinApi.RegDeleteKey(reg.getBaseKey(Relative), WinApi.PChar(Key))) 186 | } 187 | 188 | func (reg *GRegistry)DeleteValue(Name string)bool { 189 | return reg.CheckResult(WinApi.RegDeleteValue(reg.fCurrentKey, WinApi.PChar(Name))); 190 | } 191 | 192 | func (reg *GRegistry)KeyExists(Key string)bool { 193 | OldAccess := reg.fAccess 194 | reg.fAccess = WinApi.STANDARD_RIGHTS_READ | WinApi.KEY_QUERY_VALUE | 195 | WinApi.KEY_ENUMERATE_SUB_KEYS | (OldAccess & WinApi.KEY_WOW64_RES) 196 | TempKey := reg.getKey(Key) 197 | if TempKey != 0 { 198 | WinApi.RegCloseKey(TempKey) 199 | return true 200 | } 201 | reg.fAccess = OldAccess 202 | return false 203 | } 204 | 205 | func dataTypeToRegDatatype(DataType uint32)GRegDataType { 206 | switch DataType { 207 | case WinApi.REG_SZ: return RdString 208 | case WinApi.REG_EXPAND_SZ: return RdExpandString 209 | case WinApi.REG_DWORD: return RdInteger 210 | case WinApi.REG_BINARY: return RdBinary 211 | default: 212 | return RdUnknown 213 | } 214 | } 215 | 216 | func (reg *GRegistry)GetDataInfo(ValueName string)(result *GRegDataInfo,ok bool) { 217 | var DataType,datasize uint32 218 | ok = reg.CheckResult(WinApi.RegQueryValueEx(reg.fCurrentKey, WinApi.PChar(ValueName), 0, &DataType, nil, 219 | &datasize)); 220 | if ok{ 221 | result = new(GRegDataInfo) 222 | result.DataSize = datasize 223 | result.RegData = dataTypeToRegDatatype(DataType) 224 | }else{ 225 | result = nil 226 | } 227 | return 228 | } 229 | 230 | func (reg *GRegistry)ValueExists(name string)bool { 231 | _,ok := reg.GetDataInfo(name) 232 | return ok 233 | } 234 | 235 | func (reg *GRegistry)OpenKeyReadOnly(Key string)bool { 236 | Relative := !(Key != "" && Key[0]==92) 237 | if !Relative{ 238 | Key = strings.Trim(Key,"\\") 239 | } 240 | var TempKey WinApi.HKEY = 0 241 | WOWFlags := reg.fAccess & WinApi.KEY_WOW64_RES 242 | Result := reg.CheckResult(WinApi.RegOpenKeyEx(reg.getBaseKey(Relative), WinApi.PChar(Key), 0, 243 | WinApi.REGSAM(WinApi.KEY_READ | WOWFlags), &TempKey)) 244 | if Result{ 245 | reg.fAccess = WinApi.KEY_READ | WOWFlags 246 | if reg.fCurrentKey != 0 && Relative { 247 | Key = reg.fCurrentPath + "\\" + Key 248 | } 249 | reg.ChangeKey(TempKey, Key) 250 | }else { 251 | Result = reg.CheckResult(WinApi.RegOpenKeyEx(reg.getBaseKey(Relative), WinApi.PChar(Key), 0, 252 | WinApi.REGSAM(WinApi.STANDARD_RIGHTS_READ | WinApi.KEY_QUERY_VALUE | WinApi.KEY_ENUMERATE_SUB_KEYS | WOWFlags), 253 | &TempKey)) 254 | if Result{ 255 | reg.fAccess = WinApi.STANDARD_RIGHTS_READ | WinApi.KEY_QUERY_VALUE | WinApi.KEY_ENUMERATE_SUB_KEYS | WOWFlags 256 | if reg.fCurrentKey != 0 && Relative { 257 | Key = reg.fCurrentPath + "\\" + Key 258 | } 259 | reg.ChangeKey(TempKey, Key) 260 | }else{ 261 | Result = reg.CheckResult(WinApi.RegOpenKeyEx(reg.getBaseKey(Relative), WinApi.PChar(Key), 0, 262 | WinApi.REGSAM(WinApi.KEY_QUERY_VALUE | WOWFlags), &TempKey)) 263 | if Result { 264 | reg.fAccess = WinApi.KEY_QUERY_VALUE | WOWFlags 265 | if reg.fCurrentKey != 0 && Relative { 266 | Key = reg.fCurrentPath + "\\" + Key 267 | } 268 | reg.ChangeKey(TempKey, Key) 269 | } 270 | } 271 | } 272 | return Result 273 | } 274 | 275 | func (reg *GRegistry)getData(Name string,Buffer uintptr,BufSize uint32)(GRegDataType,int) { 276 | var Datatype uint32=WinApi.REG_NONE 277 | if reg.CheckResult(WinApi.RegQueryValueEx(reg.fCurrentKey, WinApi.PChar(Name), 0, &Datatype, (*byte)(unsafe.Pointer(Buffer)), &BufSize)){ 278 | return dataTypeToRegDatatype(Datatype),int(BufSize) 279 | } 280 | return RdUnknown,-1 281 | } 282 | 283 | func (reg *GRegistry)ReadInteger(Name string)(Result int) { 284 | if regdata,ret :=reg.getData(Name, uintptr(unsafe.Pointer(&Result)), uint32(unsafe.Sizeof(Result)));ret>0 && regdata==RdInteger{ 285 | return 286 | }else{ 287 | return 0 288 | } 289 | } 290 | 291 | func (reg *GRegistry)ReadBool(name string)bool { 292 | return reg.ReadInteger(name) != 0 293 | } 294 | 295 | func (reg *GRegistry)ReadString(name string)string { 296 | if regdata,ok := reg.GetDataInfo(name);ok && regdata.DataSize > 0{ 297 | result := make([]uint16,regdata.DataSize / 2) 298 | if regdata,ret := reg.getData(name,uintptr(unsafe.Pointer(&result[0])),regdata.DataSize); 299 | ret>0 && regdata == RdString || regdata == RdExpandString{ 300 | return syscall.UTF16ToString(result) 301 | } 302 | } 303 | return "" 304 | } 305 | 306 | func (reg *GRegistry)ReadFloat(name string)(Result float64) { 307 | var RLen uint32=uint32(unsafe.Sizeof(Result)) 308 | if regdata,ret :=reg.getData(name, uintptr(unsafe.Pointer(&Result)), RLen);uint32(ret)!=RLen || regdata!=RdBinary{ 309 | Result = 0 310 | } 311 | return 312 | } 313 | 314 | func regDataToDataType(Value GRegDataType) uint32 { 315 | switch Value { 316 | case RdString: return WinApi.REG_SZ 317 | case RdExpandString: return WinApi.REG_EXPAND_SZ 318 | case RdBinary: return WinApi.REG_BINARY 319 | case RdInteger: return WinApi.REG_DWORD 320 | default: 321 | return WinApi.REG_NONE 322 | } 323 | } 324 | 325 | func (reg *GRegistry)putData(Name string,Buffer uintptr,BufSize uint32,RegData GRegDataType)bool { 326 | datatype := regDataToDataType(RegData) 327 | return reg.CheckResult(WinApi.RegSetValueEx(reg.fCurrentKey, WinApi.PChar(Name), 0, datatype, Buffer, BufSize)) 328 | } 329 | 330 | func (reg *GRegistry)WriteInteger(Name string,value int)bool { 331 | return reg.putData(Name, uintptr(unsafe.Pointer(&value)), uint32(unsafe.Sizeof(value)), RdInteger) 332 | } 333 | 334 | func (reg *GRegistry)WriteBool(Name string,v bool)bool { 335 | return reg.WriteInteger(Name,int(WinApi.BoolToUint(v))) 336 | } 337 | 338 | func (reg *GRegistry)WriteFloat(Name string,v float64)bool { 339 | return reg.putData(Name, uintptr(unsafe.Pointer(&v)), uint32(unsafe.Sizeof(v)), RdBinary) 340 | } 341 | 342 | func (reg *GRegistry)WriteString(Name string,v string)bool { 343 | vbyte := syscall.StringToUTF16(v) 344 | return reg.putData(Name, uintptr(unsafe.Pointer(&vbyte[0])), uint32(2*(len(vbyte)+1)), RdString) 345 | } 346 | 347 | func (reg *GRegistry)WriteExpandString(Name string,v string)bool { 348 | vbyte := syscall.StringToUTF16(v) 349 | return reg.putData(Name, uintptr(unsafe.Pointer(&vbyte[0])), uint32(2*(len(vbyte)+1)), RdExpandString) 350 | } 351 | 352 | func (reg *GRegistry)CurrentPath()string { 353 | return reg.fCurrentPath 354 | } 355 | 356 | func (reg *GRegistry)RootKey()WinApi.HKEY { 357 | return reg.fRootKey 358 | } 359 | 360 | func (reg *GRegistry)LoadKey(Key,FileName string)bool { 361 | Relative := !(Key != "" && Key[0]==92) 362 | if !Relative{ 363 | Key = strings.Trim(Key,"\\") 364 | } 365 | return reg.CheckResult(WinApi.RegLoadKey(reg.fRootKey, WinApi.PChar(Key), WinApi.PChar(FileName))) 366 | } 367 | 368 | func (reg *GRegistry)UnLoadKey(key string)bool { 369 | Relative := !(key != "" && key[0]==92) 370 | if !Relative{ 371 | key = strings.Trim(key,"\\") 372 | } 373 | return reg.CheckResult(WinApi.RegUnLoadKey(reg.fRootKey, WinApi.PChar(key))) 374 | } 375 | 376 | func (reg *GRegistry)WriteBinaryData(Name string,buffer uintptr,BufSize uint32)bool { 377 | return reg.putData(Name, buffer, BufSize, RdBinary) 378 | } 379 | 380 | func (reg *GRegistry)ReadBinaryData(Name string,buffer uintptr,BufSize uint32)(result int) { 381 | result = -1 382 | if regdata,ok:=reg.GetDataInfo(Name);ok{ 383 | result = int(regdata.DataSize) 384 | if (regdata.RegData == RdBinary || regdata.RegData == RdUnknown) && uint32(result) <= BufSize{ 385 | reg.getData(Name, buffer, uint32(result)) 386 | } 387 | } 388 | return 389 | } 390 | func NewRegistry(access uint32)*GRegistry { 391 | reg := new(GRegistry) 392 | reg.SubInit() 393 | if access != 0{ 394 | reg.fAccess = access 395 | } 396 | return reg 397 | } -------------------------------------------------------------------------------- /Components/NVisbleControls/trayicon.go: -------------------------------------------------------------------------------- 1 | package NVisbleControls 2 | 3 | import ( 4 | "github.com/suiyunonghen/GVCL/WinApi" 5 | "github.com/suiyunonghen/GVCL/Components" 6 | "unsafe" 7 | "syscall" 8 | "github.com/suiyunonghen/GVCL/Graphics" 9 | ) 10 | 11 | type GTrayIcon struct { 12 | Components.GComponent 13 | fvisible bool 14 | fNotifyData WinApi.GNotifyIconData 15 | OnDblClick Graphics.NotifyEvent 16 | OnClick Graphics.NotifyEvent 17 | PopupMenu *GPopupMenu 18 | } 19 | 20 | type GTrayIconList struct { 21 | trayiconWnd syscall.Handle 22 | trayIcons []*GTrayIcon 23 | } 24 | 25 | var( 26 | TrayIcons *GTrayIconList 27 | ) 28 | 29 | func (iconlist *GTrayIconList)Destroy() { 30 | if iconlist.trayIcons!=nil{ 31 | for _,icon := range iconlist.trayIcons{ 32 | if icon != nil{ 33 | icon.Destroy() 34 | } 35 | } 36 | } 37 | } 38 | func (iconList *GTrayIconList)WndProc(msg uint32,IconId uint32)uintptr { 39 | icon := iconList.trayIcons[IconId-1] 40 | switch msg { 41 | case WinApi.WM_MOUSEMOVE: 42 | case WinApi.WM_LBUTTONDOWN: 43 | case WinApi.WM_LBUTTONUP: 44 | if icon.OnClick != nil{ 45 | icon.OnClick(icon) 46 | } 47 | case WinApi.WM_RBUTTONDOWN: 48 | case WinApi.WM_RBUTTONUP: 49 | if icon.PopupMenu != nil{ 50 | point := new(WinApi.POINT) 51 | WinApi.GetCursorPos(point) 52 | icon.PopupMenu.PopUp(point.X,point.Y) 53 | } 54 | case WinApi.WM_LBUTTONDBLCLK, WinApi.WM_MBUTTONDBLCLK, WinApi.WM_RBUTTONDBLCLK: 55 | if icon.OnDblClick != nil{ 56 | icon.OnDblClick(icon) 57 | } 58 | } 59 | return 0 60 | } 61 | 62 | func (iconList *GTrayIconList)SetIconWndProcHandle(wnd syscall.Handle,aicon WinApi.HICON) { 63 | if iconList.trayiconWnd == wnd{ 64 | return 65 | } 66 | iconList.trayiconWnd = wnd 67 | if iconList.trayIcons !=nil{ 68 | for _,icon := range iconList.trayIcons{ 69 | if icon != nil{ 70 | icon.fNotifyData.WND = wnd 71 | //设为应用程序图标 72 | if icon.fNotifyData.HIcon == 0{ 73 | icon.fNotifyData.HIcon = aicon 74 | } 75 | //重新显示 76 | if icon.fvisible{ 77 | WinApi.Shell_NotifyIcon(WinApi.NIM_ADD,&icon.fNotifyData) 78 | } 79 | } 80 | } 81 | } 82 | } 83 | 84 | func (iconList *GTrayIconList)GrowTrayIcon(icon *GTrayIcon)uint32 { 85 | if iconList.trayIcons==nil{ 86 | iconList.trayIcons = make([]*GTrayIcon,1) 87 | iconList.trayIcons[0] = icon 88 | return 1 89 | } 90 | for idx,icon := range iconList.trayIcons{ 91 | if icon == nil{ 92 | iconList.trayIcons[idx] = icon 93 | return uint32(idx + 1) 94 | } 95 | } 96 | iconList.trayIcons = append(iconList.trayIcons,icon) 97 | return uint32(len(iconList.trayIcons)) 98 | } 99 | 100 | func (iconList *GTrayIconList)ReciveTrayIcon(iconId uint32) { 101 | if iconList.trayIcons != nil && iconId>0 && iconId <= uint32(len(iconList.trayIcons)){ 102 | iconList.trayIcons[iconId - 1].fNotifyData.UID = 0 103 | iconList.trayIcons[iconId - 1].fNotifyData.WND = 0 104 | iconList.trayIcons[iconId - 1] = nil 105 | } 106 | } 107 | 108 | func (ticon *GTrayIcon)SubInit() { 109 | ticon.GObject.SubInit(ticon) 110 | ticon.fNotifyData.CbSize = uint32(unsafe.Sizeof(ticon.fNotifyData)) 111 | ticon.fNotifyData.UFlags = WinApi.NIF_ICON | WinApi.NIF_MESSAGE 112 | ticon.fNotifyData.UTimeout = 10000 113 | ticon.fNotifyData.UCallbackMessage = WinApi.WM_SYSTEM_TRAY_MESSAGE 114 | ticon.fNotifyData.UFlags = ticon.fNotifyData.UFlags | WinApi.NIF_TIP 115 | if TrayIcons == nil{ 116 | TrayIcons = new(GTrayIconList) 117 | } 118 | ticon.fNotifyData.UID = TrayIcons.GrowTrayIcon(ticon) 119 | ticon.fNotifyData.WND = TrayIcons.trayiconWnd 120 | } 121 | 122 | func (ticon *GTrayIcon)Destroy() { 123 | ticon.SetVisible(false) 124 | TrayIcons.ReciveTrayIcon(ticon.fNotifyData.UID) 125 | } 126 | 127 | func (ticon *GTrayIcon)SetVisible(v bool) { 128 | if ticon.fvisible!=v{ 129 | ticon.fvisible = v 130 | if ticon.fNotifyData.WND != 0{ 131 | if v{ 132 | WinApi.Shell_NotifyIcon(WinApi.NIM_ADD,&ticon.fNotifyData) 133 | }else{ 134 | WinApi.Shell_NotifyIcon(WinApi.NIM_DELETE,&ticon.fNotifyData) 135 | } 136 | } 137 | } 138 | } 139 | 140 | func (ticon *GTrayIcon)SetIcon(icoHandle WinApi.HICON) { 141 | if ticon.fNotifyData.HIcon != icoHandle{ 142 | ticon.fNotifyData.HIcon = icoHandle 143 | if ticon.fvisible && ticon.fNotifyData.HIcon != 0{ 144 | WinApi.Shell_NotifyIcon(WinApi.NIM_MODIFY,&ticon.fNotifyData) 145 | } 146 | } 147 | } 148 | 149 | func NewTrayIcon(owner interface{})*GTrayIcon { 150 | ret := new(GTrayIcon) 151 | ret.SubInit() 152 | ret.SetOwner(owner) 153 | return ret 154 | } -------------------------------------------------------------------------------- /Components/componentCore.go: -------------------------------------------------------------------------------- 1 | package Components 2 | 3 | import ( 4 | "github.com/suiyunonghen/GVCL/Graphics" 5 | "syscall" 6 | "github.com/suiyunonghen/GVCL/WinApi" 7 | ) 8 | 9 | type IComponent interface { 10 | GetName() string //组件名称 11 | SetName(fName string) //设置组件名称 12 | GetTagetData() uintptr //附加数据 13 | SetTagetData(fData uintptr) uintptr 14 | GetTag() int //附加数据 15 | SetTag(ftag int) 16 | Free() //释放数据 17 | } 18 | 19 | type IControl interface { 20 | GetColor() Graphics.GColorValue 21 | SetColor(c Graphics.GColorValue) 22 | Invalidate() //触发刷新 23 | Left() int32 24 | SetLeft(l int32) 25 | Top() int32 26 | SetTop(t int32) 27 | Width() int32 28 | SetWidth(w int32) 29 | Height() int32 30 | SetHeight(h int32) 31 | GetParent() IWincontrol 32 | Free() //释放数据 33 | GetDeviceContext()(WinApi.HDC,syscall.Handle) 34 | Visible() bool 35 | PaintControl(dc WinApi.HDC) //执行绘制 36 | Paint(cvs Graphics.ICanvas) 37 | SetBounds(ALeft, ATop, AWidth, AHeight int32) 38 | IsWindowControl()bool 39 | AfterParentWndCreate() 40 | ClientRect()WinApi.Rect 41 | Enabled()bool 42 | SetEnabled(v bool) 43 | MouseEnter() 44 | MouseLeave() 45 | MouseMove(x,y int,state KeyState)bool 46 | MouseDown(button MouseButton,x,y int,state KeyState)bool 47 | MouseUp(button MouseButton,x,y int,state KeyState)bool 48 | } 49 | 50 | type MouseButton uint8 51 | 52 | const ( 53 | MbLeft MouseButton = iota 54 | MbRight 55 | MbMiddle 56 | ) 57 | 58 | type IApplication interface { 59 | Run() 60 | Active() bool 61 | } 62 | 63 | type GCreateParams struct { 64 | Caption string 65 | Style uint32 66 | ExStyle uint32 67 | X int32 68 | Y int32 69 | Width int32 70 | Height int32 71 | WndParent syscall.Handle 72 | Param uintptr 73 | WindowClass WinApi.GWndClass 74 | WinClassName string 75 | } 76 | 77 | type IWincontrol interface { 78 | IControl 79 | GetWindowHandle() syscall.Handle 80 | CreateWnd() 81 | DestoryWnd() 82 | Focused() bool 83 | ControlCount() int 84 | WControlCount() int 85 | InsertChildWinCtrl(ctrl IWincontrol) 86 | InsertControl(ctrl IControl) 87 | RemoveChildWinCtrl(ctrl IWincontrol) 88 | RemoveControl(ctrl IControl) 89 | ControlExists(ctrl IControl) bool 90 | WindowExists(handle syscall.Handle) bool 91 | UpdateShowing() 92 | WndProc(msg uint32, wparam, lparam uintptr) (result uintptr, msgDispatchNext bool) 93 | CreateParams(params *GCreateParams) 94 | PaintWindow(dc WinApi.HDC)int32 95 | CreateWindowHandle(params *GCreateParams)bool 96 | PaintBack(dc WinApi.HDC)int32 97 | HandleAllocated()bool 98 | Perform(msg uint32,wparam, lparam uintptr)(result WinApi.LRESULT) 99 | } 100 | 101 | 102 | /** 103 | **基本组件 104 | **/ 105 | type GComponent struct { 106 | Graphics.GObject 107 | fname string `json:"Name"` 108 | ftag int `json:"Tag"` 109 | fTagetData uintptr 110 | } 111 | 112 | func (cmp *GComponent) GetName() string { 113 | return cmp.fname 114 | } 115 | 116 | func (cmp *GComponent) SetName(fName string) { 117 | cmp.fname = fName 118 | } 119 | 120 | func (cmp *GComponent) GetTagetData() uintptr { 121 | return cmp.fTagetData 122 | } 123 | 124 | func (cmp *GComponent) SetTagetData(fdata uintptr) { 125 | cmp.fTagetData = fdata 126 | } 127 | 128 | func (cmp *GComponent) GetTag() int { 129 | return cmp.ftag 130 | } 131 | 132 | func (cmp *GComponent) SetTag(fdata int) { 133 | cmp.ftag = fdata 134 | } 135 | 136 | const( 137 | MK_XBUTTON1 = 0x0020 138 | MK_XBUTTON2 = 0x0040 139 | ) 140 | //键盘状态 141 | type KeyState uint32 142 | 143 | func (state KeyState)CtrlKeyDown()bool { 144 | return state & WinApi.MK_CONTROL != 0 145 | } 146 | 147 | func (state KeyState)LButtonDown()bool { 148 | return state & WinApi.MK_LBUTTON != 0 149 | } 150 | 151 | func (state KeyState)MButtonDown()bool { 152 | return state & WinApi.MK_MBUTTON != 0 153 | } 154 | 155 | func (state KeyState)RButtonDown()bool { 156 | 157 | return state & WinApi.MK_RBUTTON != 0 158 | } 159 | 160 | func (state KeyState)ShiftKeyDown()bool { 161 | return state & WinApi.MK_SHIFT != 0 162 | } 163 | 164 | func (state KeyState)AltKeyDown()bool { 165 | return WinApi.GetKeyState(WinApi.VK_MENU) < 0 166 | } 167 | 168 | func (state KeyState)XBUTTON1Down()bool { 169 | return MK_XBUTTON1 & state != 0 170 | } 171 | 172 | func (state KeyState)XBUTTON2Down()bool { 173 | return MK_XBUTTON2 & state != 0 174 | } 175 | 176 | func (state *KeyState)SetCtrlKeyDown(v bool) { 177 | *state = KeyState(uint32(*state) | WinApi.MK_CONTROL) 178 | } 179 | 180 | -------------------------------------------------------------------------------- /Graphics/baseobj.go: -------------------------------------------------------------------------------- 1 | package Graphics 2 | 3 | import ( 4 | "reflect" 5 | ) 6 | 7 | type NotifyEvent func(sender interface{}) 8 | type GDispatchObj struct { 9 | TargetObject interface{} 10 | DispatchHandler reflect.Value 11 | } 12 | 13 | type IInheritedObject interface { 14 | SubChild(idx int) interface{} 15 | SubChildCount() int 16 | Destroy() 17 | Owner()interface{} 18 | OwnerChildCount()int 19 | OwnerChild(idx int)interface{} 20 | RemoveOwnerChild(obj interface{}) 21 | SetOwner(aowner interface{}) 22 | AddOwnerChild(obj interface{}) 23 | } 24 | 25 | type GObject struct { 26 | fSubChilds []interface{} //子对象 27 | fOwner interface{} 28 | fOwnerList []interface{} 29 | TagData interface{} 30 | } 31 | 32 | func (obj *GObject)SetOwner(aowner interface{}) { 33 | var targetobj interface{} 34 | if i := obj.SubChildCount() - 1; i >= 0{ 35 | targetobj = obj.SubChild(i) 36 | }else{ 37 | targetobj = obj 38 | } 39 | if obj.fOwner != nil{ 40 | obj.fOwner.(IInheritedObject).RemoveOwnerChild(targetobj) 41 | } 42 | obj.fOwner = aowner 43 | if aowner != nil{ 44 | aowner.(IInheritedObject).AddOwnerChild(targetobj) 45 | } 46 | } 47 | 48 | func (obj *GObject)AddOwnerChild(childobj interface{}) { 49 | if obj.fOwnerList == nil{ 50 | obj.fOwnerList =make([]interface{},1) 51 | obj.fOwnerList[0] = childobj 52 | }else{ 53 | obj.fOwnerList = append(obj.fOwnerList,childobj) 54 | } 55 | } 56 | 57 | func (obj *GObject)Owner()interface{} { 58 | return obj.fOwner 59 | } 60 | 61 | func (obj *GObject)RemoveOwnerChild(delobj interface{}) { 62 | if obj.fOwnerList!= nil{ 63 | delobj.(*GObject).fOwner =nil 64 | for k,v := range obj.fOwnerList{ 65 | if v == delobj{ 66 | obj.fOwnerList = append(obj.fOwnerList[:k],obj.fOwnerList[k+1:]) 67 | } 68 | } 69 | } 70 | } 71 | 72 | func (obj *GObject) OwnerChild(idx int) interface{} { 73 | if obj.fOwnerList == nil { 74 | return nil 75 | } 76 | if idx >= 0 && idx < len(obj.fOwnerList) { 77 | return obj.fOwnerList[idx] 78 | } 79 | return nil 80 | } 81 | 82 | func (obj *GObject)OwnerChildCount()int { 83 | if obj.fOwner != nil{ 84 | return len(obj.fOwnerList) 85 | } 86 | return 0 87 | } 88 | 89 | func (obj *GObject)Free() { 90 | //执行Destroy过程 91 | if i := obj.SubChildCount() - 1; i >= 0{ 92 | obj.SubChild(i).(IInheritedObject).Destroy() 93 | 94 | }else{ 95 | obj.Destroy() 96 | } 97 | } 98 | 99 | func (obj *GObject)Destroy() { 100 | //释放的过程,后面继承的重写此方法则可 101 | if obj.fOwnerList != nil { 102 | for i := 0;i= 0 && idx < len(obj.fSubChilds) { 129 | return obj.fSubChilds[idx] 130 | } 131 | return nil 132 | } 133 | 134 | func (obj *GObject)RealObject()interface{} { 135 | if i := obj.SubChildCount() -1;i>=0{ 136 | return obj.SubChild(i) 137 | }else{ 138 | return obj 139 | } 140 | } 141 | 142 | func (obj *GObject) SubChildCount() int { 143 | if obj.fSubChilds == nil { 144 | return 0 145 | } 146 | return len(obj.fSubChilds) 147 | } 148 | -------------------------------------------------------------------------------- /Graphics/canvas.go: -------------------------------------------------------------------------------- 1 | package Graphics 2 | import ( 3 | "github.com/suiyunonghen/GVCL/WinApi" 4 | ) 5 | 6 | type GCanvas struct { 7 | GObject 8 | fHandle WinApi.HDC 9 | fBrush *GBrush 10 | fFont *GFont 11 | fPen *GPen 12 | } 13 | 14 | 15 | type ICanvas interface { 16 | GetHandle()WinApi.HDC 17 | SetHandle(dc WinApi.HDC) 18 | MoveTo(x,y int32) 19 | GetClipRect(*WinApi.Rect) 20 | FrameRect(r *WinApi.Rect) 21 | FillRect(r *WinApi.Rect) 22 | LineTo(x,y int) 23 | Brush()*GBrush 24 | Pen()*GPen 25 | Font()*GFont 26 | CreateHandle() 27 | TextExtent(str string,size *WinApi.GSize)bool 28 | TextWidth(str string)(int32,bool) 29 | TextHeight(str string)(int32,bool) 30 | Draw(x,y int,graphic IGraphic) 31 | } 32 | 33 | func NewCanvas()*GCanvas { 34 | cvs := new(GCanvas) 35 | cvs.SubInit() 36 | return cvs 37 | } 38 | 39 | func (cvs *GCanvas) SubInit() { 40 | cvs.GObject.SubInit(cvs) 41 | } 42 | 43 | func (cvs *GCanvas) TextExtent(str string,size *WinApi.GSize)bool { 44 | if cvs.GetHandle() != 0{ 45 | r := new(WinApi.Rect) 46 | r.Right = 10000 47 | r.Bottom = 10000 48 | WinApi.DrawText(cvs.fHandle,str,-1,r,WinApi.DT_LEFT | WinApi.DT_TOP | WinApi.DT_CALCRECT) 49 | size.CX = r.Width() 50 | size.CY = r.Height() 51 | return true 52 | } 53 | return false 54 | } 55 | 56 | func (cvs *GCanvas) TextWidth(str string)(w int32,b bool) { 57 | w = 0 58 | b = cvs.GetHandle() != 0 59 | if b{ 60 | r := new(WinApi.Rect) 61 | WinApi.DrawText(cvs.fHandle,str,-1,r,WinApi.DT_LEFT | WinApi.DT_TOP) 62 | w = r.Width() 63 | } 64 | return 65 | } 66 | 67 | func (cvs *GCanvas)Draw(x,y int,graphic IGraphic){ 68 | dc := cvs.GetHandle() 69 | if dc != 0{ 70 | graphic.Draw(x,y,cvs.GetHandle()) 71 | } 72 | } 73 | 74 | 75 | func (cvs *GCanvas) TextHeight(str string)(h int32, b bool) { 76 | h = 0 77 | b = cvs.GetHandle() != 0 78 | if b{ 79 | r := new(WinApi.Rect) 80 | WinApi.DrawText(cvs.fHandle,str,-1,r,WinApi.DT_LEFT | WinApi.DT_TOP) 81 | h = r.Width() 82 | } 83 | return 84 | } 85 | 86 | func (cvs *GCanvas)CreateHandle() { 87 | if cvs.fHandle!=0{ 88 | cvs.RefreshCanvasState() 89 | } 90 | } 91 | 92 | func (cvs *GCanvas)RefreshCanvasState() { 93 | if cvs.fBrush == nil{ 94 | cvs.fBrush = NewBrush() 95 | } 96 | if cvs.fFont == nil{ 97 | cvs.fFont = NewFont() 98 | } 99 | if cvs.fPen == nil{ 100 | cvs.fPen = NewPen() 101 | } 102 | WinApi.UnrealizeObject(uintptr(cvs.fBrush.Handle)) 103 | WinApi.SelectObject(cvs.fHandle,uintptr(cvs.fBrush.Handle)) 104 | if cvs.fBrush.BrushStyle == BSSolid{ 105 | WinApi.SetBkColor(cvs.fHandle, uint32(cvs.fBrush.Color)) 106 | WinApi.SetBkMode(cvs.fHandle, WinApi.OPAQUE) 107 | }else{ 108 | WinApi.SetBkColor(cvs.fHandle, ^uint32(cvs.fBrush.Color)) 109 | WinApi.SetBkMode(cvs.fHandle, WinApi.TRANSPARENT) 110 | } 111 | WinApi.SelectObject(cvs.fHandle,uintptr(cvs.fFont.FontHandle)) 112 | WinApi.SetTextColor(cvs.fHandle, uint32(cvs.fFont.Color)) 113 | 114 | WinApi.SelectObject(cvs.fHandle,uintptr(cvs.fPen.Handle)) 115 | } 116 | 117 | func (cvs *GCanvas)Destroy() { 118 | if cvs.fFont != nil{ 119 | cvs.fFont.Destroy() 120 | cvs.fFont = nil 121 | } 122 | 123 | if cvs.fBrush != nil{ 124 | cvs.fBrush.Destroy() 125 | cvs.fBrush = nil 126 | } 127 | 128 | if cvs.fPen != nil{ 129 | cvs.fPen.Destroy() 130 | cvs.fPen = nil 131 | } 132 | } 133 | 134 | func (cvs *GCanvas)GetHandle()WinApi.HDC { 135 | if cvs.fHandle == 0{ 136 | var target interface{} 137 | if i := cvs.SubChildCount() - 1; i >= 0{ 138 | target = cvs.SubChild(i) 139 | }else{ 140 | target = cvs 141 | } 142 | target.(ICanvas).CreateHandle() 143 | }else{ 144 | cvs.RefreshCanvasState() 145 | } 146 | return cvs.fHandle 147 | } 148 | 149 | func (cvs *GCanvas)SetHandle(dc WinApi.HDC) { 150 | if cvs.fHandle == dc{ 151 | return 152 | } 153 | var penPos *WinApi.POINT = nil 154 | if cvs.fHandle != 0{ 155 | penPos = new(WinApi.POINT) 156 | WinApi.GetCurrentPositionEx(cvs.fHandle,penPos) 157 | } 158 | cvs.fHandle = dc 159 | if cvs.fHandle !=0 && penPos != nil{ 160 | cvs.MoveTo(int32(penPos.X),int32(penPos.Y)) 161 | } 162 | } 163 | 164 | func (cvs *GCanvas)MoveTo(x,y int32) { 165 | if cvs.GetHandle() != 0{ 166 | WinApi.MoveToEx(cvs.fHandle,x,y,nil) 167 | } 168 | } 169 | 170 | func (cvs *GCanvas)GetClipRect(rect *WinApi.Rect) { 171 | if cvs.GetHandle() != 0{ 172 | WinApi.GetClipBox(cvs.fHandle,rect) 173 | } 174 | } 175 | 176 | func (cvs *GCanvas)GetPenPos(pt *WinApi.POINT) { 177 | if cvs.GetHandle() !=0{ 178 | WinApi.GetCurrentPositionEx(cvs.fHandle,pt) 179 | } 180 | } 181 | 182 | func (cvs *GCanvas)FrameRect(r *WinApi.Rect) { 183 | if cvs.GetHandle() !=0{ 184 | WinApi.FrameRect(cvs.fHandle,r,cvs.fBrush.Handle) 185 | } 186 | } 187 | 188 | func (cvs *GCanvas)FillRect(r *WinApi.Rect) { 189 | if cvs.GetHandle() !=0 { 190 | WinApi.FillRect(cvs.fHandle,r,cvs.fBrush.Handle) 191 | } 192 | } 193 | 194 | func (cvs *GCanvas)LineTo(x,y int) { 195 | if cvs.GetHandle() != 0{ 196 | WinApi.LineTo(cvs.fHandle,x,y) 197 | } 198 | } 199 | 200 | func (cvs *GCanvas)Brush()*GBrush { 201 | if cvs.fBrush == nil{ 202 | cvs.fBrush = NewBrush() 203 | } 204 | return cvs.fBrush 205 | } 206 | 207 | func (cvs *GCanvas)Pen()*GPen { 208 | if cvs.fPen == nil{ 209 | cvs.fPen = NewPen() 210 | } 211 | return cvs.fPen 212 | } 213 | 214 | func (cvs *GCanvas)Font()*GFont { 215 | if cvs.fFont == nil{ 216 | cvs.fFont = NewFont() 217 | } 218 | return cvs.fFont 219 | } 220 | 221 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GVCL 2 | Golang Windows GUI Bindings Like Delphi VCL 3 | Windows的GUI界面Go语言封装,目标是实现一个类似Delphi VCL版本效果的界面库 4 | # 使用方法 5 | ##### `msgbox.go` 6 | 7 | ```go 8 | type GForm1 struct { 9 | controls.GForm 10 | Button1 *controls.GButton 11 | Edit1 *controls.GEdit 12 | } 13 | 14 | func NewForm1(app *controls.WApplication)*GForm1{ 15 | frm := new(GForm1) 16 | frm.SubInit() 17 | frm.Button1 = controls.NewButton(frm) 18 | frm.Button1.SetWidth(80) 19 | frm.Button1.SetHeight(30) 20 | frm.Button1.SetLeft(frm.Width() - 90) 21 | frm.Button1.SetTop(frm.Height() - 80) 22 | frm.Button1.SetCaption("确定关闭") 23 | 24 | frm.Edit1 = controls.NewEdit(frm) 25 | frm.OnClose = func(sender interface{},closeAction *int8) { 26 | *closeAction = controls.CAFree 27 | } 28 | frm.Button1.OnClick = func(sender interface{}) { 29 | WinApi.MessageBox(frm.GetWindowHandle(),"sadf","Asdf",64) 30 | frm.SetModalResult(controls.MrOK) 31 | } 32 | return frm 33 | } 34 | 35 | func main() { 36 | app := new(controls.WApplication) 37 | app.ShowMainForm = true 38 | m := app.CreateForm() 39 | m.SetLeft(200) 40 | m.SetTop(50) 41 | m.SetCaption("测试窗体") 42 | 43 | e := controls.NewEdit(m) 44 | e.SetName("Edit1") 45 | e.SetLeft(10) 46 | e.SetWidth(100) 47 | e.SetHeight(20) 48 | e.SetCaption("测试") 49 | b := controls.NewButton(m) 50 | b.SetDefault(true) 51 | b.SetLeft(120) 52 | b.SetCaption("创建窗体") 53 | b.OnClick = func(sender interface{}) { 54 | tmpm := NewForm1(app) 55 | tmpm.SetCaption(e.GetText()) 56 | if tmpm.ShowModal() == controls.MrOK{ 57 | WinApi.MessageBox(tmpm.GetWindowHandle(),"程序确定退出","消息",64) 58 | } 59 | } 60 | 61 | b1 := controls.NewButton(m) 62 | b1.SetCaption("关闭") 63 | b1.SetLeft(100) 64 | b1.SetTop(40) 65 | b1.OnClick = func(sender interface{}) { 66 | b.SetVisible(!b.Visible()) 67 | b.SetCaption("测试") 68 | } 69 | app.Run() 70 | } 71 | ``` 72 | 73 | ##### Create Manifest `test.manifest` 74 | 75 | ```xml 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | ``` 86 | 87 | Then either compile the manifest using the [rsrc tool](https://github.com/akavel/rsrc), like this: 88 | 89 | go get github.com/akavel/rsrc 90 | rsrc -manifest test.manifest -o rsrc.syso 91 | 92 | or rename the `test.manifest` file to `test.exe.manifest` and distribute it with the application instead. 93 | 94 | 使用Go Build 建立文件,会将这个manifest资源包含进去,以使用系统皮肤 95 | 96 | ### Font使用 97 | 98 | ```go 99 | b1.Font.BeginUpdate() 100 | b1.Font.SetSize(10) 101 | b1.Font.Underline = 1 102 | b1.Font.EndUpdate() 103 | ``` 104 | ### 增加弹出菜单组件 105 | 菜单使用方法 106 | ```go 107 | //菜单 108 | pop := NVisbleControls.NewPopupMenu(m) 109 | tmpitem := pop.Items().AddItem("测试1") 110 | citem := tmpitem.AddItem("子测试1") 111 | citem.OnClick = func(sender interface{}) { 112 | WinApi.MessageBox(m.GetWindowHandle(),"菜单测试"+sender.(*NVisbleControls.GMenuItem).Caption(),"消息",64) 113 | } 114 | citem = pop.Items().AddItem("测试2") 115 | citem.OnClick = func(sender interface{}) { 116 | WinApi.MessageBox(m.GetWindowHandle(),"菜单测试"+sender.(*NVisbleControls.GMenuItem).Caption(),"消息",64) 117 | } 118 | m.PopupMenu = pop 119 | ``` 120 | 目前整体组件框架已经具备雏形,要增加其他组件库按照扩展的Button和Edit以及Label增加则可,下一步做完托盘就暂时放一段落 121 | 122 | ### 增加托盘组件完成,使用方法 123 | ```go 124 | //菜单 125 | pop := NVisbleControls.NewPopupMenu(m) 126 | tmpitem := pop.Items().AddItem("测试1") 127 | citem := tmpitem.AddItem("子测试1") 128 | citem.OnClick = func(sender interface{}) { 129 | WinApi.MessageBox(m.GetWindowHandle(),"菜单测试"+sender.(*NVisbleControls.GMenuItem).Caption(),"消息",64) 130 | } 131 | citem = pop.Items().AddItem("测试2") 132 | citem.OnClick = func(sender interface{}) { 133 | WinApi.MessageBox(m.GetWindowHandle(),"菜单测试"+sender.(*NVisbleControls.GMenuItem).Caption(),"消息",64) 134 | } 135 | //托盘图标,结合弹出菜单 136 | icon := NVisbleControls.NewTrayIcon(m) 137 | icon.SetIcon(app.AppIcon()) //设置托盘图标 138 | //icon.SetIcon(WinApi.LoadIcon(controls.Hinstance,uintptr(5))) 139 | icon.SetVisible(true) 140 | icon.PopupMenu = pop //设置托盘的右键弹出菜单 141 | icon.OnDblClick = func(sender interface{}) { 142 | if !m.Visible(){ 143 | m.Show() 144 | }else{ 145 | m.SetVisible(false) 146 | } 147 | } 148 | ``` 149 | ### 增加注册表操作类库,使用方法 150 | ``` 151 | reg := NVisbleControls.NewRegistry(0) 152 | reg.SetRootKey(WinApi.HKEY_LOCAL_MACHINE) 153 | if reg.OpenKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",false){ 154 | if reg.ValueExists("SynTPEnh"){ 155 | WinApi.MessageBox(m.GetWindowHandle(),"SynTPEnh自动启动: "+reg.ReadString("SynTPEnh"),"消息",64) 156 | } 157 | WinApi.MessageBox(m.GetWindowHandle(),"打开注册表测试"+sender.(*NVisbleControls.GMenuItem).Caption(),"消息",6) 158 | } 159 | reg.Free() 160 | ``` 161 | 运行效果 162 | ![运行效果](https://github.com/suiyunonghen/GVCL/blob/master/test/GVCL.png) 163 | -------------------------------------------------------------------------------- /WinApi/WinStructs.go: -------------------------------------------------------------------------------- 1 | package WinApi 2 | 3 | import ( 4 | "syscall" 5 | "time" 6 | "unsafe" 7 | ) 8 | 9 | type HMENU uintptr 10 | type HINST uintptr 11 | type ATOM uint16 12 | type HICON uintptr 13 | type HCURSOR uintptr 14 | type HBRUSH uintptr 15 | type HPEN uintptr 16 | type HKL uintptr 17 | type HDC uintptr 18 | type HOOK uintptr 19 | type LRESULT int 20 | type HBITMAP uintptr 21 | type HGDIOBJ uintptr 22 | type HPALETTE uintptr 23 | 24 | func HiWord(L uint32) uint16 { 25 | return uint16(L >> 16) 26 | } 27 | 28 | func LoWord(L uint32)uint16 { 29 | return uint16(L) 30 | } 31 | 32 | type POINT struct { 33 | X, Y int32 34 | } 35 | 36 | func (pt *POINT)PtInRect(r *Rect)bool{ 37 | /*ret,_,_ := syscall.Syscall(fnPtInRect,2,uintptr(unsafe.Pointer(r)),uintptr(unsafe.Pointer(pt)),0) 38 | return ret!=0*/ 39 | return pt.X >= r.Left && pt.X <= r.Right && pt.Y>=r.Top && pt.Y <= r.Bottom 40 | } 41 | 42 | type Rect struct { 43 | Left,Top int32 44 | Right,Bottom int32 45 | } 46 | 47 | type GSize struct { 48 | CX,CY int32 49 | } 50 | 51 | func (rect *Rect)Width()int32{ 52 | return rect.Right-rect.Left 53 | } 54 | 55 | func (rect *Rect)Height() int32{ 56 | return rect.Bottom-rect.Top 57 | } 58 | 59 | func (rect *Rect)PtInRect(pt *POINT) bool{ 60 | /*ret,_,_ := syscall.Syscall(fnPtInRect,3,uintptr(unsafe.Pointer(rect)),uintptr(pt.X),uintptr(pt.Y)) 61 | return ret!=0*/ 62 | return pt.X >= rect.Left && pt.X <= rect.Right && pt.Y>=rect.Top && pt.Y <= rect.Bottom 63 | } 64 | 65 | func (rect *Rect)GetClientRect(hWnd syscall.Handle)bool { 66 | ret,_,_ := syscall.Syscall(fnGetClientRect,2,uintptr(hWnd),uintptr(unsafe.Pointer(rect)),0) 67 | return ret!=0 68 | } 69 | 70 | func (rect *Rect)GetWindowRect(hWnd syscall.Handle)bool { 71 | ret,_,_ := syscall.Syscall(fnGetWindowRect,2,uintptr(hWnd),uintptr(unsafe.Pointer(rect)),0) 72 | return ret!=0 73 | } 74 | 75 | func (rect *Rect)AdjustWindowRect(dwStyle uint32,bMenu bool)bool { 76 | ret,_,_ := syscall.Syscall(fnAdjustWindowRect,3,uintptr(unsafe.Pointer(rect)),uintptr(dwStyle),uintptr(BoolToUint(bMenu))) 77 | return ret!=0 78 | } 79 | 80 | func (rect *Rect)AdjustWindowRectEx(dwStyle uint32,bMenu bool,dwExStyle uint32)bool { 81 | ret,_,_ := syscall.Syscall6(fnAdjustWindowRect,4,uintptr(unsafe.Pointer(rect)),uintptr(dwStyle),uintptr(BoolToUint(bMenu)), 82 | uintptr(dwExStyle),0,0) 83 | return ret!=0 84 | } 85 | 86 | func (rc *Rect)InflateRect(dx,dy int)bool { 87 | ret,_,_:=syscall.Syscall(fnInflateRect,3,uintptr(unsafe.Pointer(rc)),uintptr(dx),uintptr(dy)) 88 | return ret!=0 89 | } 90 | 91 | func (rc *Rect)SetRectEmpty()bool { 92 | ret,_,_:=syscall.Syscall(fnSetRectEmpty,1,uintptr(unsafe.Pointer(rc)),0,0) 93 | return ret!=0 94 | } 95 | 96 | func (rc *Rect)IsRectEmpty()bool{ 97 | ret,_,_:=syscall.Syscall(fnIsRectEmpty,1,uintptr(unsafe.Pointer(rc)),0,0) 98 | return ret!=0 99 | } 100 | 101 | func (rc *Rect)OffsetRect(dx,dy int)bool{ 102 | ret,_,_:=syscall.Syscall(fnOffsetRect,3,uintptr(unsafe.Pointer(rc)),uintptr(dx),uintptr(dy)) 103 | return ret!=0 104 | } 105 | 106 | type tagWNDCLASSW struct { 107 | Style uint32 108 | FnWndProc uintptr 109 | CbClsExtra int32 110 | CbWndExtra int32 111 | HInstance HINST 112 | HIcon HICON 113 | HCursor HCURSOR 114 | HbrBackground HBRUSH 115 | LpszMenuName *uint16 116 | LpszClassName *uint16 117 | } 118 | 119 | type GWndClass tagWNDCLASSW 120 | 121 | type tagWNDCLASSEXW struct { 122 | CbSize uint32 123 | Style uint32 124 | FnWndProc uintptr 125 | CbClsExtra int32 126 | CbWndExtra int32 127 | HInstance HINST 128 | HIcon HICON 129 | HCursor HCURSOR 130 | HbrBackground HBRUSH 131 | LpszMenuName *uint16 132 | LpszClassName *uint16 133 | HIconSm HICON 134 | } 135 | 136 | type GWndClassEx tagWNDCLASSEXW 137 | 138 | func (wndClass *GWndClass) GetClassInfo(lpClassName string) bool { 139 | var ret uintptr 140 | if lpClassName!=""{ 141 | ret, _, _ = syscall.Syscall(fnGetClassInfoW, 3, 142 | uintptr(wndClass.HInstance),uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpClassName))), 143 | uintptr(unsafe.Pointer(wndClass))) 144 | }else{ 145 | ret, _, _ = syscall.Syscall(fnGetClassInfoW, 3, 146 | uintptr(wndClass.HInstance), uintptr(unsafe.Pointer(wndClass.LpszClassName)), 147 | uintptr(unsafe.Pointer(wndClass))) 148 | } 149 | return ret != 0 150 | } 151 | 152 | func (wndClass *GWndClassEx) GetClassInfoEx(lpClassName string) bool { 153 | wndClass.CbSize = uint32(unsafe.Sizeof(*wndClass)) 154 | ret, _, _ := syscall.Syscall(fnGetClassInfoExW, 3, 155 | uintptr(wndClass.HInstance), uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpClassName))), 156 | uintptr(unsafe.Pointer(wndClass))) 157 | return ret != 0 158 | } 159 | 160 | func (wndClass *GWndClass)RegisterClass() ATOM { 161 | ret, _, _ := syscall.Syscall(fnRegisterClassW, 1, 162 | uintptr(unsafe.Pointer(wndClass)), 163 | 0, 164 | 0) 165 | return ATOM(ret) 166 | } 167 | 168 | 169 | func (wndClass *GWndClassEx)RegisterClassEx() ATOM { 170 | wndClass.CbSize = uint32(unsafe.Sizeof(*wndClass)) 171 | ret, _, _ := syscall.Syscall(fnRegisterClassExW, 1, 172 | uintptr(unsafe.Pointer(wndClass)), 173 | 0, 174 | 0) 175 | return ATOM(ret) 176 | } 177 | 178 | 179 | type MSG struct { 180 | HWnd syscall.Handle 181 | Message uint32 182 | WParam uintptr 183 | LParam uintptr 184 | Time uint32 185 | Pt POINT 186 | } 187 | 188 | func (msg *MSG)TranslateMessage() bool { 189 | ret, _, _ := syscall.Syscall(fnTranslateMessage, 1, 190 | uintptr(unsafe.Pointer(msg)), 191 | 0, 192 | 0) 193 | 194 | return ret != 0 195 | } 196 | 197 | func (msg *MSG)DispatchMessage() uintptr { 198 | ret, _, _ := syscall.Syscall(fnDispatchMessageW, 1, 199 | uintptr(unsafe.Pointer(msg)), 200 | 0, 201 | 0) 202 | 203 | return ret 204 | } 205 | 206 | func (lpMsg *MSG)PeekMessage(hWnd syscall.Handle, wMsgFilterMin, wMsgFilterMax, wRemoveMsg uint32) bool { 207 | ret, _, _ := syscall.Syscall6(fnPeekMessageW, 5, 208 | uintptr(unsafe.Pointer(lpMsg)), 209 | uintptr(hWnd), 210 | uintptr(wMsgFilterMin), 211 | uintptr(wMsgFilterMax), 212 | uintptr(wRemoveMsg), 213 | 0) 214 | 215 | return ret != 0 216 | } 217 | 218 | func (lpmsg *MSG)CallMsgFilter(nCode int32)bool{ 219 | ret,_,_:=syscall.Syscall(fnCallMsgFilterW,2,uintptr(unsafe.Pointer(lpmsg)),uintptr(nCode),0) 220 | return ret!=0 221 | } 222 | 223 | type GPaintStruct struct { 224 | Hdc HDC 225 | Erase bool 226 | PaintRect Rect 227 | Restore bool 228 | IncUpdate bool 229 | RgbReserved [32]byte 230 | } 231 | 232 | func (pstruct *GPaintStruct)BeginPaint(hWnd syscall.Handle)HDC{ 233 | ret, _, _ := syscall.Syscall(fnBeginPaint, 2, uintptr(hWnd),uintptr(unsafe.Pointer(pstruct)),0) 234 | return HDC(ret) 235 | } 236 | 237 | func (pstruct *GPaintStruct)EndPaint(hWnd syscall.Handle) bool{ 238 | ret, _, _ := syscall.Syscall(fnEndPaint, 2, uintptr(hWnd),uintptr(unsafe.Pointer(pstruct)),0) 239 | return ret!=0 240 | } 241 | 242 | type GdevicemodeW struct { 243 | DmDeviceName [32]uint16//array[0..CCHDEVICENAME - 1] of WideChar; 244 | DmSpecVersion uint16 245 | DmDriverVersion uint16 246 | DmSize uint16 247 | DmDriverExtra uint16 248 | DmFields uint16 249 | DmOrientation int16 250 | DmPaperSize int16 251 | DmPaperLength int16 252 | DmPaperWidth int16 253 | DmScale int16 254 | DmCopies int16 255 | DmDefaultSource int16 256 | DmPrintQuality int16 257 | DmColor int16 258 | DmDuplex int16 259 | DmYResolution int16 260 | DmTTOption int16 261 | DmCollate int16 262 | DmFormName [32]uint16 263 | DmLogPixels uint16 264 | DmBitsPerPel uint32 265 | DmPelsWidth uint32 266 | DmPelsHeight uint32 267 | DmDisplayFlags uint32 268 | DmDisplayFrequency uint32 269 | DmICMMethod uint32 270 | DmICMIntent uint32 271 | DmMediaType uint32 272 | DmDitherType uint32 273 | DmICCManufacturer uint32 274 | DmICCModel uint32 275 | DmPanningWidth uint32 276 | DmPanningHeight uint32 277 | } 278 | 279 | type GDrawTextParams struct { 280 | CbSize uint32 281 | TabLength int32 282 | LeftMargin int32 283 | RightMargin int32 284 | LengthDrawn uint32 285 | } 286 | 287 | type GLOGFONT struct { 288 | Height int32 289 | Width int32 290 | Escapement int32 291 | Orientation int32 292 | Weight int32 293 | Italic byte 294 | Underline byte 295 | StrikeOut byte 296 | CharSet byte 297 | OutPrecision byte 298 | ClipPrecision byte 299 | Quality byte 300 | PitchAndFamily byte 301 | FaceName [32]uint16 302 | } 303 | 304 | type GMenuItemInfo struct{ 305 | CbSize uint32 306 | FMask uint32 307 | FType uint32 308 | FState uint32 309 | WID uint32 310 | HSubMenu HMENU 311 | HbmpChecked HBITMAP 312 | HbmpUnchecked HBITMAP 313 | DwItemData uintptr 314 | DwTypeData uintptr 315 | Cch uint32 316 | HbmpItem HBITMAP 317 | } 318 | 319 | func (logFont *GLOGFONT)CreateFont()syscall.Handle { 320 | ret,_,_ := syscall.Syscall(fnCreateFontIndirectW,1,uintptr(unsafe.Pointer(logFont)),0,0) 321 | return syscall.Handle(ret) 322 | } 323 | 324 | type GLogBrush struct { 325 | Style uint32 326 | Color uint32 327 | Hatch uintptr 328 | } 329 | 330 | func (logbrush *GLogBrush)CreateBrush()HBRUSH { 331 | ret,_,_ := syscall.Syscall(fnCreateBrushIndirect,1,uintptr(unsafe.Pointer(logbrush)),0,0) 332 | return HBRUSH(ret) 333 | } 334 | 335 | type GLOGPEN struct { 336 | Style uint32 337 | Width POINT 338 | Color uint32 339 | } 340 | 341 | func (logpen *GLOGPEN)CreatePen()HPEN { 342 | ret,_,_ := syscall.Syscall(fnCreatePenIndirect,1,uintptr(unsafe.Pointer(logpen)),0,0) 343 | return HPEN(ret) 344 | } 345 | 346 | func PChar(str string)*uint16 { 347 | return syscall.StringToUTF16Ptr(str) 348 | } 349 | 350 | func PCharUintptr(str string)uintptr { 351 | return uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(str))) 352 | } 353 | 354 | type tagNMHDR struct{ 355 | HwndFrom syscall.Handle 356 | IdFrom uintptr 357 | NMCode int 358 | } 359 | 360 | type GNMHDR tagNMHDR 361 | 362 | 363 | type CIEXYZ struct { 364 | CiexyzX, CiexyzY, CiexyzZ int32 // FXPT2DOT30 365 | } 366 | 367 | type CIEXYZTRIPLE struct { 368 | CiexyzRed, CiexyzGreen, CiexyzBlue CIEXYZ 369 | } 370 | 371 | type BITMAPINFOHEADER struct { 372 | BiSize uint32 373 | BiWidth int32 374 | BiHeight int32 375 | BiPlanes uint16 376 | BiBitCount uint16 377 | BiCompression uint32 378 | BiSizeImage uint32 379 | BiXPelsPerMeter int32 380 | BiYPelsPerMeter int32 381 | BiClrUsed uint32 382 | BiClrImportant uint32 383 | } 384 | 385 | type BITMAPV4HEADER struct { 386 | BITMAPINFOHEADER 387 | BV4RedMask uint32 388 | BV4GreenMask uint32 389 | BV4BlueMask uint32 390 | BV4AlphaMask uint32 391 | BV4CSType uint32 392 | BV4Endpoints CIEXYZTRIPLE 393 | BV4GammaRed uint32 394 | BV4GammaGreen uint32 395 | BV4GammaBlue uint32 396 | } 397 | 398 | type BITMAPV5HEADER struct { 399 | BITMAPV4HEADER 400 | BV5Intent uint32 401 | BV5ProfileData uint32 402 | BV5ProfileSize uint32 403 | BV5Reserved uint32 404 | } 405 | 406 | type RGBQUAD struct { 407 | RgbBlue byte 408 | RgbGreen byte 409 | RgbRed byte 410 | RgbReserved byte 411 | } 412 | 413 | func (rgb RGBQUAD)RGBA() (r, g, b, a uint32) { 414 | return uint32(rgb.RgbRed)<< 8,uint32(rgb.RgbGreen)<< 8,uint32(rgb.RgbBlue)<< 8,uint32(rgb.RgbReserved)<< 8 415 | } 416 | 417 | type PALETTEENTRY struct { 418 | Red byte 419 | Green byte 420 | Blue byte 421 | Flags byte 422 | } 423 | 424 | //为了兼容go自带的image接口,然后做相关的encode,所以,必须将所获分量全部左移8位 425 | func (rgb PALETTEENTRY)RGBA() (r, g, b, a uint32) { 426 | return uint32(rgb.Red)<< 8,uint32(rgb.Green)<< 8,uint32(rgb.Blue)<< 8,uint32(rgb.Flags)<< 8 427 | } 428 | 429 | type LOGPALETTE struct { 430 | Version uint16 431 | NumEntries uint16 432 | PalEntry [256]PALETTEENTRY 433 | } 434 | 435 | 436 | type BITMAPINFO struct { 437 | BmiHeader BITMAPINFOHEADER 438 | BmiColors RGBQUAD 439 | } 440 | 441 | type BITMAPINFO8 struct { 442 | BmiHeader BITMAPINFOHEADER 443 | BmiColors [256]RGBQUAD 444 | } 445 | 446 | type BITMAP struct { 447 | BmType int32 448 | BmWidth int32 449 | BmHeight int32 450 | BmWidthBytes int32 451 | BmPlanes uint16 452 | BmBitsPixel uint16 453 | BmBits unsafe.Pointer 454 | } 455 | 456 | type DIBSECTION struct { 457 | DsBm BITMAP 458 | DsBmih BITMAPINFOHEADER 459 | DsBitfields [3]uint32 460 | DshSection syscall.Handle 461 | DsOffset uint32 462 | } 463 | 464 | 465 | type BLENDFUNCTION struct { 466 | BlendOp byte 467 | BlendFlags byte 468 | SourceConstantAlpha byte 469 | AlphaFormat byte 470 | } 471 | 472 | type GSystemTime struct { 473 | Year uint16 474 | Month uint16 475 | DayOfWeek uint16 476 | Day uint16 477 | Hour uint16 478 | Minute uint16 479 | Second uint16 480 | Milliseconds uint16 481 | } 482 | 483 | func (sysTime GSystemTime)Time()time.Time { 484 | return time.Date(int(sysTime.Year),time.Month(sysTime.Month),int(sysTime.Day),int(sysTime.Hour),int(sysTime.Minute), 485 | int(sysTime.Second),int(time.Duration(sysTime.Milliseconds) * time.Millisecond),time.Local) 486 | } 487 | 488 | func (sysTime *GSystemTime)From(t time.Time) { 489 | year,month,day := t.Date() 490 | sysTime.Year = uint16(year) 491 | sysTime.Month = uint16(month) 492 | sysTime.Day = uint16(day) 493 | year,m,day := t.Clock() 494 | sysTime.Hour = uint16(year) 495 | sysTime.Minute = uint16(m) 496 | sysTime.Second = uint16(day) 497 | sysTime.Milliseconds = uint16(time.Duration(t.Nanosecond()) / time.Millisecond) 498 | } -------------------------------------------------------------------------------- /WinApi/comctl32.go: -------------------------------------------------------------------------------- 1 | package WinApi 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | var ( 9 | libcomctl32 syscall.Handle 10 | fnInitCommonControlsEx uintptr 11 | fnImageList_Create uintptr 12 | fnImageList_Destroy uintptr 13 | fnImageList_GetImageCount uintptr 14 | fnImageList_SetImageCount uintptr 15 | fnImageList_Add uintptr 16 | fnImageList_ReplaceIcon uintptr 17 | fnImageList_SetBkColor uintptr 18 | fnImageList_GetBkColor uintptr 19 | fnImageList_SetOverlayImage uintptr 20 | fnImageList_Draw uintptr 21 | fnImageList_Replace uintptr 22 | fnImageList_AddMasked uintptr 23 | fnImageList_DrawEx uintptr 24 | fnImageList_DrawIndirect uintptr 25 | fnImageList_Remove uintptr 26 | fnImageList_GetIcon uintptr 27 | fnImageList_LoadImageA uintptr 28 | fnImageList_LoadImageW uintptr 29 | fnImageList_Copy uintptr 30 | fnImageList_BeginDrag uintptr 31 | fnImageList_EndDrag uintptr 32 | fnImageList_DragEnter uintptr 33 | fnImageList_DragLeave uintptr 34 | fnImageList_DragMove uintptr 35 | fnImageList_SetDragCursorImage uintptr 36 | fnImageList_DragShowNolock uintptr 37 | fnImageList_GetDragImage uintptr 38 | ) 39 | 40 | type tagINITCOMMONCONTROLSEX struct { 41 | dwSize uint 42 | dwICC uint 43 | } 44 | 45 | type GInitCommonControlsEX tagINITCOMMONCONTROLSEX 46 | 47 | func init() { 48 | libcomctl32, _ = syscall.LoadLibrary("comctl32.dll") 49 | fnInitCommonControlsEx, _ = syscall.GetProcAddress(libcomctl32, "InitCommonControlsEx") 50 | fnImageList_Create, _ = syscall.GetProcAddress(libcomctl32, "ImageList_Create") 51 | fnImageList_Destroy, _ = syscall.GetProcAddress(libcomctl32, "ImageList_Destroy") 52 | fnImageList_GetImageCount, _ = syscall.GetProcAddress(libcomctl32, "ImageList_GetImageCount") 53 | fnImageList_SetImageCount, _ = syscall.GetProcAddress(libcomctl32, "ImageList_SetImageCount") 54 | fnImageList_Add, _ = syscall.GetProcAddress(libcomctl32, "ImageList_Add") 55 | fnImageList_ReplaceIcon, _ = syscall.GetProcAddress(libcomctl32, "ImageList_ReplaceIcon") 56 | fnImageList_SetBkColor, _ = syscall.GetProcAddress(libcomctl32, "ImageList_SetBkColor") 57 | fnImageList_GetBkColor, _ = syscall.GetProcAddress(libcomctl32, "ImageList_GetBkColor") 58 | fnImageList_SetOverlayImage, _ = syscall.GetProcAddress(libcomctl32, "ImageList_SetOverlayImage") 59 | fnImageList_Draw, _ = syscall.GetProcAddress(libcomctl32, "ImageList_Draw") 60 | fnImageList_Replace, _ = syscall.GetProcAddress(libcomctl32, "ImageList_Replace") 61 | fnImageList_AddMasked, _ = syscall.GetProcAddress(libcomctl32, "ImageList_AddMasked") 62 | fnImageList_DrawEx, _ = syscall.GetProcAddress(libcomctl32, "ImageList_DrawEx") 63 | fnImageList_DrawIndirect, _ = syscall.GetProcAddress(libcomctl32, "ImageList_DrawIndirect") 64 | fnImageList_Remove, _ = syscall.GetProcAddress(libcomctl32, "ImageList_Remove") 65 | 66 | fnImageList_GetIcon, _ = syscall.GetProcAddress(libcomctl32, "ImageList_GetIcon") 67 | fnImageList_LoadImageA, _ = syscall.GetProcAddress(libcomctl32, "ImageList_LoadImageA") 68 | fnImageList_LoadImageW, _ = syscall.GetProcAddress(libcomctl32, "ImageList_LoadImageW") 69 | fnImageList_Copy, _ = syscall.GetProcAddress(libcomctl32, "ImageList_Copy") 70 | fnImageList_BeginDrag, _ = syscall.GetProcAddress(libcomctl32, "ImageList_BeginDrag") 71 | fnImageList_EndDrag, _ = syscall.GetProcAddress(libcomctl32, "ImageList_EndDrag") 72 | fnImageList_DragEnter, _ = syscall.GetProcAddress(libcomctl32, "ImageList_DragEnter") 73 | fnImageList_DragLeave, _ = syscall.GetProcAddress(libcomctl32, "ImageList_DragLeave") 74 | fnImageList_DragMove, _ = syscall.GetProcAddress(libcomctl32, "ImageList_DragMove") 75 | fnImageList_SetDragCursorImage, _ = syscall.GetProcAddress(libcomctl32, "ImageList_SetDragCursorImage") 76 | fnImageList_DragShowNolock, _ = syscall.GetProcAddress(libcomctl32, "ImageList_DragShowNolock") 77 | fnImageList_GetDragImage, _ = syscall.GetProcAddress(libcomctl32, "ImageList_GetDragImage") 78 | } 79 | 80 | func InitCommonControlsEx(ICC *GInitCommonControlsEX) bool { 81 | if fnInitCommonControlsEx != 0 { 82 | ret, _, _ := syscall.Syscall(fnInitCommonControlsEx, 1, uintptr(unsafe.Pointer(ICC)), 0, 0) 83 | return ret != 0 84 | } 85 | return false 86 | } 87 | -------------------------------------------------------------------------------- /WinApi/mpr.go: -------------------------------------------------------------------------------- 1 | package WinApi 2 | 3 | import ( 4 | "syscall" 5 | ) 6 | 7 | var ( 8 | libmpr syscall.Handle 9 | fnMultinetGetConnectionPerformanceW uintptr 10 | fnMultinetGetConnectionPerformanceA uintptr 11 | fnWNetAddConnection2W uintptr 12 | fnWNetAddConnection2A uintptr 13 | fnWNetAddConnection3W uintptr 14 | fnWNetAddConnection3A uintptr 15 | fnWNetAddConnectionW uintptr 16 | fnWNetAddConnectionA uintptr 17 | fnWNetCancelConnection2W uintptr 18 | fnWNetCancelConnection2A uintptr 19 | fnWNetCancelConnectionW uintptr 20 | fnWNetCancelConnectionA uintptr 21 | fnWNetCloseEnum uintptr 22 | fnWNetConnectionDialog1W uintptr 23 | fnWNetConnectionDialog1A uintptr 24 | fnWNetConnectionDialog uintptr 25 | fnWNetDisconnectDialog1W uintptr 26 | fnWNetDisconnectDialog1A uintptr 27 | fnWNetDisconnectDialog uintptr 28 | fnWNetEnumResourceW uintptr 29 | fnWNetEnumResourceA uintptr 30 | fnWNetGetConnectionW uintptr 31 | fnWNetGetConnectionA uintptr 32 | fnWNetGetLastErrorW uintptr 33 | fnWNetGetLastErrorA uintptr 34 | fnWNetGetNetworkInformationW uintptr 35 | fnWNetGetNetworkInformationA uintptr 36 | fnWNetGetProviderNameW uintptr 37 | fnWNetGetProviderNameA uintptr 38 | fnWNetGetResourceParentW uintptr 39 | fnWNetGetResourceParentA uintptr 40 | fnWNetGetUniversalNameW uintptr 41 | fnWNetGetUniversalNameA uintptr 42 | fnWNetGetUserW uintptr 43 | fnWNetGetUserA uintptr 44 | fnWNetOpenEnumW uintptr 45 | fnWNetOpenEnumA uintptr 46 | fnWNetSetConnectionW uintptr 47 | fnWNetSetConnectionA uintptr 48 | fnWNetUseConnectionW uintptr 49 | fnWNetUseConnectionA uintptr 50 | ) 51 | 52 | func init() { 53 | libmpr, _ = syscall.LoadLibrary("mpr.dll") 54 | fnMultinetGetConnectionPerformanceW, _ = syscall.GetProcAddress(libmpr, "MultinetGetConnectionPerformanceW") 55 | fnMultinetGetConnectionPerformanceA, _ = syscall.GetProcAddress(libmpr, "MultinetGetConnectionPerformanceA") 56 | fnWNetAddConnection2W, _ = syscall.GetProcAddress(libmpr, "WNetAddConnection2W") 57 | fnWNetAddConnection2A, _ = syscall.GetProcAddress(libmpr, "WNetAddConnection2A") 58 | fnWNetAddConnection3W, _ = syscall.GetProcAddress(libmpr, "WNetAddConnection3W") 59 | fnWNetAddConnection3A, _ = syscall.GetProcAddress(libmpr, "WNetAddConnection3A") 60 | fnWNetAddConnectionW, _ = syscall.GetProcAddress(libmpr, "WNetAddConnectionW") 61 | fnWNetAddConnectionA, _ = syscall.GetProcAddress(libmpr, "WNetAddConnectionA") 62 | fnWNetCancelConnection2W, _ = syscall.GetProcAddress(libmpr, "WNetCancelConnection2W") 63 | fnWNetCancelConnection2A, _ = syscall.GetProcAddress(libmpr, "WNetCancelConnection2A") 64 | fnWNetCancelConnectionW, _ = syscall.GetProcAddress(libmpr, "WNetCancelConnectionW") 65 | fnWNetCancelConnectionA, _ = syscall.GetProcAddress(libmpr, "WNetCancelConnectionA") 66 | fnWNetCloseEnum, _ = syscall.GetProcAddress(libmpr, "WNetCloseEnum") 67 | fnWNetConnectionDialog1W, _ = syscall.GetProcAddress(libmpr, "WNetConnectionDialog1W") 68 | fnWNetConnectionDialog1A, _ = syscall.GetProcAddress(libmpr, "WNetConnectionDialog1A") 69 | fnWNetConnectionDialog, _ = syscall.GetProcAddress(libmpr, "WNetConnectionDialog") 70 | fnWNetDisconnectDialog1W, _ = syscall.GetProcAddress(libmpr, "WNetDisconnectDialog1W") 71 | fnWNetDisconnectDialog1A, _ = syscall.GetProcAddress(libmpr, "WNetDisconnectDialog1A") 72 | fnWNetDisconnectDialog, _ = syscall.GetProcAddress(libmpr, "WNetDisconnectDialog") 73 | fnWNetEnumResourceW, _ = syscall.GetProcAddress(libmpr, "WNetEnumResourceW") 74 | fnWNetEnumResourceA, _ = syscall.GetProcAddress(libmpr, "WNetEnumResourceA") 75 | fnWNetGetConnectionW, _ = syscall.GetProcAddress(libmpr, "WNetGetConnectionW") 76 | fnWNetGetConnectionA, _ = syscall.GetProcAddress(libmpr, "WNetGetConnectionA") 77 | fnWNetGetLastErrorW, _ = syscall.GetProcAddress(libmpr, "WNetGetLastErrorW") 78 | fnWNetGetLastErrorA, _ = syscall.GetProcAddress(libmpr, "WNetGetLastErrorA") 79 | fnWNetGetNetworkInformationW, _ = syscall.GetProcAddress(libmpr, "WNetGetNetworkInformationW") 80 | fnWNetGetNetworkInformationA, _ = syscall.GetProcAddress(libmpr, "WNetGetNetworkInformationA") 81 | fnWNetGetProviderNameW, _ = syscall.GetProcAddress(libmpr, "WNetGetProviderNameW") 82 | fnWNetGetProviderNameA, _ = syscall.GetProcAddress(libmpr, "WNetGetProviderNameA") 83 | fnWNetGetResourceParentW, _ = syscall.GetProcAddress(libmpr, "WNetGetResourceParentW") 84 | fnWNetGetResourceParentA, _ = syscall.GetProcAddress(libmpr, "WNetGetResourceParentA") 85 | fnWNetGetUniversalNameW, _ = syscall.GetProcAddress(libmpr, "WNetGetUniversalNameW") 86 | fnWNetGetUniversalNameA, _ = syscall.GetProcAddress(libmpr, "WNetGetUniversalNameA") 87 | fnWNetGetUserW, _ = syscall.GetProcAddress(libmpr, "WNetGetUserW") 88 | fnWNetGetUserA, _ = syscall.GetProcAddress(libmpr, "WNetGetUserA") 89 | fnWNetOpenEnumW, _ = syscall.GetProcAddress(libmpr, "WNetOpenEnumW") 90 | fnWNetOpenEnumA, _ = syscall.GetProcAddress(libmpr, "WNetOpenEnumA") 91 | fnWNetSetConnectionW, _ = syscall.GetProcAddress(libmpr, "WNetSetConnectionW") 92 | fnWNetSetConnectionA, _ = syscall.GetProcAddress(libmpr, "WNetSetConnectionA") 93 | fnWNetUseConnectionW, _ = syscall.GetProcAddress(libmpr, "WNetUseConnectionW") 94 | fnWNetUseConnectionA, _ = syscall.GetProcAddress(libmpr, "WNetUseConnectionA") 95 | } 96 | -------------------------------------------------------------------------------- /WinApi/msimg32.go: -------------------------------------------------------------------------------- 1 | package WinApi 2 | 3 | import ( 4 | "syscall" 5 | ) 6 | 7 | var ( 8 | libmsimg32 syscall.Handle 9 | fnAlphaBlend uintptr 10 | fnAlphaDIBBlend uintptr 11 | fnGradientFill uintptr 12 | fnTransparentBlt uintptr 13 | ) 14 | 15 | func init() { 16 | libmsimg32, _ = syscall.LoadLibrary("msimg32.dll") 17 | fnAlphaBlend, _ = syscall.GetProcAddress(libmsimg32, "AlphaBlend") 18 | fnAlphaDIBBlend, _ = syscall.GetProcAddress(libmsimg32, "AlphaDIBBlend") 19 | fnGradientFill, _ = syscall.GetProcAddress(libmsimg32, "GradientFill") 20 | fnTransparentBlt, _ = syscall.GetProcAddress(libmsimg32, "TransparentBlt") 21 | } 22 | -------------------------------------------------------------------------------- /WinApi/opengl32.go: -------------------------------------------------------------------------------- 1 | package WinApi 2 | 3 | import ( 4 | "syscall" 5 | ) 6 | 7 | var ( 8 | libopengl32 syscall.Handle 9 | fnwglCopyContext uintptr 10 | fnwglCreateContext uintptr 11 | fnwglCreateLayerContext uintptr 12 | fnwglDeleteContext uintptr 13 | fnwglDescribeLayerPlane uintptr 14 | fnwglGetCurrentContext uintptr 15 | fnwglGetCurrentDC uintptr 16 | fnwglGetLayerPaletteEntries uintptr 17 | fnwglMakeCurrent uintptr 18 | fnwglRealizeLayerPalette uintptr 19 | fnwglSetLayerPaletteEntries uintptr 20 | fnwglShareLists uintptr 21 | fnwglSwapLayerBuffers uintptr 22 | fnwglSwapMultipleBuffers uintptr 23 | fnwglUseFontBitmapsW uintptr 24 | fnwglUseFontOutlinesW uintptr 25 | fnwglUseFontBitmapsA uintptr 26 | fnwglUseFontOutlinesA uintptr 27 | ) 28 | 29 | func init() { 30 | libopengl32, _ = syscall.LoadLibrary("opengl32.dll") 31 | fnwglCopyContext, _ = syscall.GetProcAddress(libopengl32, "wglCopyContext") 32 | fnwglCreateContext, _ = syscall.GetProcAddress(libopengl32, "wglCreateContext") 33 | fnwglCreateLayerContext, _ = syscall.GetProcAddress(libopengl32, "wglCreateLayerContext") 34 | fnwglDeleteContext, _ = syscall.GetProcAddress(libopengl32, "wglDeleteContext") 35 | fnwglDescribeLayerPlane, _ = syscall.GetProcAddress(libopengl32, "wglDescribeLayerPlane") 36 | fnwglGetCurrentContext, _ = syscall.GetProcAddress(libopengl32, "wglGetCurrentContext") 37 | fnwglGetCurrentDC, _ = syscall.GetProcAddress(libopengl32, "wglGetCurrentDC") 38 | fnwglGetLayerPaletteEntries, _ = syscall.GetProcAddress(libopengl32, "wglGetLayerPaletteEntries") 39 | fnwglMakeCurrent, _ = syscall.GetProcAddress(libopengl32, "wglMakeCurrent") 40 | fnwglRealizeLayerPalette, _ = syscall.GetProcAddress(libopengl32, "wglRealizeLayerPalette") 41 | fnwglSetLayerPaletteEntries, _ = syscall.GetProcAddress(libopengl32, "wglSetLayerPaletteEntries") 42 | fnwglShareLists, _ = syscall.GetProcAddress(libopengl32, "wglShareLists") 43 | fnwglSwapLayerBuffers, _ = syscall.GetProcAddress(libopengl32, "wglSwapLayerBuffers") 44 | fnwglSwapMultipleBuffers, _ = syscall.GetProcAddress(libopengl32, "wglSwapMultipleBuffers") 45 | fnwglUseFontBitmapsW, _ = syscall.GetProcAddress(libopengl32, "wglUseFontBitmapsW") 46 | fnwglUseFontOutlinesW, _ = syscall.GetProcAddress(libopengl32, "wglUseFontOutlinesW") 47 | fnwglUseFontBitmapsA, _ = syscall.GetProcAddress(libopengl32, "wglUseFontBitmapsA") 48 | fnwglUseFontOutlinesA, _ = syscall.GetProcAddress(libopengl32, "wglUseFontOutlinesA") 49 | } 50 | -------------------------------------------------------------------------------- /WinApi/shellapi.go: -------------------------------------------------------------------------------- 1 | package WinApi 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | type GNotifyIconData struct { 9 | CbSize uint32 10 | WND syscall.Handle 11 | UID uint32 12 | UFlags uint32 13 | UCallbackMessage uint32 14 | HIcon HICON 15 | SZTip [128]uint16 16 | DWState uint32 17 | DWStateMask uint32 18 | SZInfo [256]uint16 19 | UTimeout uint32 20 | SZInfoTitle [64]uint16 21 | DWInfoFlags uint32 22 | GUIDItem syscall.GUID 23 | HBalloonIcon HICON 24 | } 25 | 26 | const( 27 | NIM_ADD = 0X00000000 28 | NIM_MODIFY = 0X00000001 29 | NIM_DELETE = 0X00000002 30 | NIM_SETFOCUS = 0X00000003 31 | NIM_SETVERSION = 0X00000004 32 | NOTIFYICON_VERSION = 3 33 | NOTIFYICON_VERSION_4 = 4 34 | NIF_MESSAGE = 0X00000001 35 | NIF_ICON = 0X00000002 36 | NIF_TIP = 0X00000004 37 | NIF_STATE = 0X00000008 38 | NIF_INFO = 0X00000010 39 | NIF_GUID = 0X00000020 40 | NIF_REALTIME = 0X00000040 41 | NIF_SHOWTIP = 0X00000080 42 | NIS_HIDDEN = 0X00000001 43 | NIS_SHAREDICON = 0X00000002 44 | NIIF_NONE = 0X00000000 45 | NIIF_INFO = 0X00000001 46 | NIIF_WARNING = 0X00000002 47 | NIIF_ERROR = 0X00000003 48 | NIIF_USER = 0X00000004 49 | NIIF_ICON_MASK = 0X0000000F 50 | NIIF_NOSOUND = 0X00000010 51 | NIIF_LARGE_ICON = 0X00000020 52 | NIIF_RESPECT_QUIET_TIME = 0X00000080 53 | 54 | NIN_SELECT = 0X0400 55 | NINF_KEY = 0X1 56 | NIN_KEYSELECT = NIN_SELECT | NINF_KEY 57 | 58 | NIN_BALLOONSHOW = 0X0400 + 2 59 | NIN_BALLOONHIDE = 0X0400 + 3 60 | NIN_BALLOONTIMEOUT = 0X0400 + 4 61 | NIN_BALLOONUSERCLICK = 0X0400 + 5 62 | NIN_POPUPOPEN = 0X0400 + 6 63 | NIN_POPUPCLOSE = 0X0400 + 7 64 | WM_SYSTEM_TRAY_MESSAGE = WM_USER + 1 65 | ) 66 | 67 | var( 68 | fnShell_NotifyIcon uintptr 69 | libshell32 syscall.Handle 70 | fnShellExecuteW uintptr 71 | fnExtractIconExW uintptr 72 | ) 73 | 74 | func init() { 75 | libshell32, _ = syscall.LoadLibrary("shell32.dll") 76 | fnShell_NotifyIcon, _ = syscall.GetProcAddress(libshell32, "Shell_NotifyIconW") 77 | fnShellExecuteW,_ = syscall.GetProcAddress(libshell32, "ShellExecuteW") 78 | fnExtractIconExW,_= syscall.GetProcAddress(libshell32, "ExtractIconExW") 79 | } 80 | 81 | func Shell_NotifyIcon(dwMessage uint32, lpData *GNotifyIconData)bool{ 82 | ret,_,_ := syscall.Syscall(fnShell_NotifyIcon,2,uintptr(dwMessage),uintptr(unsafe.Pointer(lpData)),0) 83 | return ret != 0 84 | } 85 | 86 | func ShellExecute(hwnd syscall.Handle,Operation, FileName, Parameters,Directory uintptr,ShowCmd int)HINST { 87 | ret,_,_ := syscall.Syscall6(fnShellExecuteW,6,uintptr(hwnd),Operation, FileName, Parameters,Directory,uintptr(ShowCmd)) 88 | return HINST(ret) 89 | } 90 | 91 | func GetModuleFileName(hModule syscall.Handle) string { 92 | var fileName [260]uint16; 93 | ret,_,_ := syscall.SyscallN(fnGetModuleFileNameW,uintptr(hModule),uintptr(unsafe.Pointer(&fileName[0])),uintptr(260)) 94 | if ret != 0{ 95 | return syscall.UTF16ToString(fileName[:ret]) 96 | } 97 | return "" 98 | } 99 | 100 | func ExtractIconEx(fileName string,nIconIndex int,phiconLarge *HICON,phiconSmall *HICON,nIcons uint)uint { 101 | if fileName == ""{ 102 | fileName = GetModuleFileName(0) 103 | } 104 | pfileName,err := syscall.UTF16PtrFromString(fileName) 105 | if err != nil{ 106 | return 0 107 | } 108 | ret,_,_ := syscall.SyscallN(fnExtractIconExW,uintptr(unsafe.Pointer(pfileName)),uintptr(nIconIndex), 109 | uintptr(unsafe.Pointer(phiconLarge)),uintptr(unsafe.Pointer(phiconSmall)),uintptr(nIcons)) 110 | return uint(ret) 111 | } -------------------------------------------------------------------------------- /WinApi/version.go: -------------------------------------------------------------------------------- 1 | package WinApi 2 | 3 | import ( 4 | "fmt" 5 | "syscall" 6 | "unsafe" 7 | ) 8 | 9 | var ( 10 | libversion syscall.Handle 11 | fnGetFileVersionInfoW uintptr 12 | fnGetFileVersionInfoA uintptr 13 | fnGetFileVersionInfoSizeW uintptr 14 | fnGetFileVersionInfoSizeA uintptr 15 | fnVerFindFileW uintptr 16 | fnVerFindFileA uintptr 17 | fnVerInstallFileW uintptr 18 | fnVerInstallFileA uintptr 19 | fnVerQueryValueW uintptr 20 | fnVerQueryValueA uintptr 21 | ) 22 | 23 | type GVSFixedFileInfo struct{ 24 | DWSignature uint32 25 | DWStrucVersion uint32 26 | DWFileVersionMS uint32 27 | DWFileVersionLS uint32 28 | DWProductVersionMS uint32 29 | DWProductVersionLS uint32 30 | DWFileFlagsMask uint32 31 | DWFileFlags uint32 32 | DWFileOS uint32 33 | DWFileType uint32 34 | DWFileSubtype uint32 35 | DWFileDateMS uint32 36 | DWFileDateLS uint32 37 | } 38 | 39 | type GVersion struct { 40 | Major uint16 41 | Minor uint16 42 | SmallVer uint16 43 | Build uint16 44 | } 45 | 46 | func (v GVersion)String() string { 47 | return fmt.Sprintf("%d.%d.%d.%d",v.Major,v.Minor,v.SmallVer, v.Build) 48 | } 49 | 50 | func init() { 51 | libversion, _ = syscall.LoadLibrary("version.dll") 52 | fnGetFileVersionInfoW, _ = syscall.GetProcAddress(libversion, "GetFileVersionInfoW") 53 | fnGetFileVersionInfoA, _ = syscall.GetProcAddress(libversion, "GetFileVersionInfoA") 54 | fnGetFileVersionInfoSizeW, _ = syscall.GetProcAddress(libversion, "GetFileVersionInfoSizeW") 55 | fnGetFileVersionInfoSizeA, _ = syscall.GetProcAddress(libversion, "GetFileVersionInfoSizeA") 56 | fnVerFindFileW, _ = syscall.GetProcAddress(libversion, "VerFindFileW") 57 | fnVerFindFileA, _ = syscall.GetProcAddress(libversion, "VerFindFileA") 58 | fnVerInstallFileW, _ = syscall.GetProcAddress(libversion, "VerInstallFileW") 59 | fnVerInstallFileA, _ = syscall.GetProcAddress(libversion, "VerInstallFileA") 60 | fnVerQueryValueW, _ = syscall.GetProcAddress(libversion, "VerQueryValueW") 61 | fnVerQueryValueA, _ = syscall.GetProcAddress(libversion, "VerQueryValueA") 62 | } 63 | 64 | func GetFileVersionInfoSize(fileName *uint16,lpdwHandle *uint32)uint32 { 65 | ret,_,_ :=syscall.Syscall(fnGetFileVersionInfoSizeW,2,uintptr(unsafe.Pointer(fileName)),uintptr(unsafe.Pointer(lpdwHandle)),0) 66 | return uint32(ret) 67 | } 68 | 69 | func GetFileVersionInfo(fileName *uint16,dwHandle, dwLen uint32,lpData unsafe.Pointer)bool { 70 | ret,_,_ :=syscall.Syscall6(fnGetFileVersionInfoW,4,uintptr(unsafe.Pointer(fileName)), 71 | uintptr(dwHandle),uintptr(dwLen),uintptr(lpData),0,0) 72 | return ret !=0 73 | } 74 | 75 | func VerQueryValue(pBlock uintptr,lpSubBlock *uint16,lplpBuffer uintptr,puLen *uint32)bool { 76 | ret,_,_ :=syscall.Syscall6(fnVerQueryValueW,4,pBlock, 77 | uintptr(unsafe.Pointer(lpSubBlock)),uintptr(unsafe.Pointer(lplpBuffer)),uintptr(unsafe.Pointer(puLen)),0,0) 78 | return ret !=0 79 | } 80 | 81 | func GetProductVersion(fileName string)(fileVersion GVersion,prodVersion GVersion,ok bool) { 82 | ok = false 83 | fileptr := syscall.StringToUTF16Ptr(fileName) 84 | var wnd uint32 85 | if InfoSize := GetFileVersionInfoSize(fileptr,&wnd);InfoSize != 0{ 86 | verbuffer := make([]byte,InfoSize) 87 | var FI *GVSFixedFileInfo 88 | var VerSize uint32 89 | if GetFileVersionInfo(fileptr,wnd,InfoSize,unsafe.Pointer(&verbuffer[0]))&& 90 | VerQueryValue(uintptr(unsafe.Pointer(&verbuffer[0])),syscall.StringToUTF16Ptr("\\"),uintptr(unsafe.Pointer(&FI)), 91 | &VerSize){ 92 | fileVersion.Major = HiWord(FI.DWFileVersionMS) 93 | fileVersion.Minor = LoWord(FI.DWFileVersionMS) 94 | fileVersion.SmallVer = HiWord(FI.DWFileVersionLS) 95 | fileVersion.Build = LoWord(FI.DWFileVersionLS) 96 | 97 | prodVersion.Major = HiWord(FI.DWProductVersionMS) 98 | prodVersion.Minor = LoWord(FI.DWProductVersionMS) 99 | prodVersion.SmallVer = HiWord(FI.DWProductVersionLS) 100 | prodVersion.Build = LoWord(FI.DWProductVersionLS) 101 | ok = true 102 | return 103 | } 104 | } 105 | return 106 | } 107 | 108 | -------------------------------------------------------------------------------- /WinApi/winsock2.go: -------------------------------------------------------------------------------- 1 | package WinApi 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | var ( 9 | winSock2dll syscall.Handle 10 | fnioctlsocket uintptr 11 | ) 12 | 13 | 14 | 15 | const( 16 | IPPROTO_IP = 0; // dummy for IP 17 | IPPROTO_HOPOPTS = 0; // IPv6 hop-by-hop options 18 | IPPROTO_ICMP = 1; // control message protocol 19 | IPPROTO_IGMP = 2; // internet group management protocol 20 | IPPROTO_GGP = 3; // gateway^2 (deprecated) 21 | IPPROTO_IPV4 = 4; // IPv4 22 | IPPROTO_ST = 5; 23 | IPPROTO_TCP = 6; // tcp 24 | IPPROTO_CBT = 7; 25 | IPPROTO_EGP = 8; 26 | IPPROTO_IGP = 9; 27 | IPPROTO_PUP = 12; // pup 28 | IPPROTO_UDP = 17; // user datagram protocol 29 | IPPROTO_IDP = 22; // xns idp 30 | IPPROTO_RDP = 27; 31 | IPPROTO_IPV6 = 41; // IPv6 32 | IPPROTO_ROUTING = 43; // IPv6 routing header 33 | IPPROTO_FRAGMENT = 44; // IPv6 fragmentation header 34 | IPPROTO_ESP = 50; // IPsec ESP header 35 | IPPROTO_AH = 51; // IPsec AH 36 | IPPROTO_ICMPV6 = 58; // ICMPv6 37 | IPPROTO_NONE = 59; // IPv6 no next header 38 | IPPROTO_DSTOPTS = 60; // IPv6 destination options 39 | IPPROTO_ND = 77; // UNOFFICIAL net disk proto 40 | IPPROTO_ICLFXBM = 78; 41 | IPPROTO_PIM = 103; 42 | IPPROTO_PGM = 113; 43 | IPPROTO_L2TP = 115; 44 | IPPROTO_SCTP = 132; 45 | 46 | IPPROTO_RAW = 255; // raw IP packet 47 | IPPROTO_MAX = 256; 48 | // 49 | // These are reserved for internal use by Windows. 50 | // 51 | IPPROTO_RESERVED_RAW = 257; 52 | IPPROTO_RESERVED_IPSEC = 258; 53 | IPPROTO_RESERVED_IPSECOFFLOAD = 259; 54 | IPPROTO_RESERVED_MAX = 260; 55 | 56 | // 57 | // Port/socket numbers: network standard functions 58 | // 59 | 60 | IPPORT_TCPMUX = 1; 61 | IPPORT_ECHO = 7; 62 | IPPORT_DISCARD = 9; 63 | IPPORT_SYSTAT = 11; 64 | IPPORT_DAYTIME = 13; 65 | IPPORT_NETSTAT = 15; 66 | IPPORT_QOTD = 17; 67 | IPPORT_MSP = 18; 68 | IPPORT_CHARGEN = 19; 69 | IPPORT_FTP_DATA = 20; 70 | IPPORT_FTP = 21; 71 | IPPORT_TELNET = 23; 72 | IPPORT_SMTP = 25; 73 | IPPORT_TIMESERVER = 37; 74 | IPPORT_NAMESERVER = 42; 75 | IPPORT_WHOIS = 43; 76 | IPPORT_MTP = 57; 77 | 78 | // 79 | // Port/socket numbers: host specific functions 80 | // 81 | 82 | IPPORT_TFTP = 69; 83 | IPPORT_RJE = 77; 84 | IPPORT_FINGER = 79; 85 | IPPORT_TTYLINK = 87; 86 | IPPORT_SUPDUP = 95; 87 | 88 | // 89 | // UNIX TCP sockets 90 | // 91 | IPPORT_POP3 = 110; 92 | IPPORT_NTP = 123; 93 | IPPORT_EPMAP = 135; 94 | IPPORT_NETBIOS_NS = 137; 95 | IPPORT_NETBIOS_DGM = 138; 96 | IPPORT_NETBIOS_SSN = 139; 97 | IPPORT_IMAP = 143; 98 | IPPORT_SNMP = 161; 99 | IPPORT_SNMP_TRAP = 162; 100 | IPPORT_IMAP3 = 220; 101 | IPPORT_LDAP = 389; 102 | IPPORT_HTTPS = 443; 103 | IPPORT_MICROSOFT_DS = 445; 104 | 105 | IPPORT_EXECSERVER = 512; 106 | IPPORT_LOGINSERVER = 513; 107 | IPPORT_CMDSERVER = 514; 108 | IPPORT_EFSSERVER = 520; 109 | 110 | // 111 | // UNIX UDP sockets 112 | // 113 | 114 | IPPORT_BIFFUDP = 512; 115 | IPPORT_WHOSERVER = 513; 116 | IPPORT_ROUTESERVER = 520; 117 | 118 | // 520+1 also used 119 | 120 | // 121 | // Ports < IPPORT_RESERVED are reserved for 122 | // privileged processes (e.g. root). 123 | // 124 | 125 | IPPORT_RESERVED = 1024; 126 | 127 | IPPORT_REGISTERED_MIN = IPPORT_RESERVED; 128 | IPPORT_REGISTERED_MAX = 0xbfff; 129 | IPPORT_DYNAMIC_MIN = 0xc000; 130 | IPPORT_DYNAMIC_MAX = 0xffff; 131 | 132 | 133 | FIONBIO = syscall.IOC_IN | ((4 & 0x7f) << 16) | (102 << 8) | 126 // set/clear non-blocking i/o 134 | 135 | IP_OPTIONS = 1 136 | IP_HDRINCL = 2 137 | IP_TOS = 3 138 | IP_TTL = 4 139 | IP_MULTICAST_IF = 9 140 | 141 | ) 142 | 143 | func init() { 144 | winSock2dll, _ = syscall.LoadLibrary("ws2_32.dll") 145 | fnioctlsocket,_ = syscall.GetProcAddress(winSock2dll, "ioctlsocket") 146 | } 147 | 148 | 149 | func Ioctlsocket(sockHandle syscall.Handle,cmd uint32,arpg *uint32)int { 150 | r1, _, _ := syscall.Syscall(fnioctlsocket,3,uintptr(sockHandle),uintptr(cmd),uintptr(unsafe.Pointer(arpg))) 151 | return int(r1) 152 | } 153 | -------------------------------------------------------------------------------- /WinApi/wintrust.go: -------------------------------------------------------------------------------- 1 | package WinApi 2 | 3 | import ( 4 | "syscall" 5 | ) 6 | 7 | var ( 8 | libwintrust syscall.Handle 9 | fnWinLoadTrustProvider uintptr 10 | fnWinSubmitCertificate uintptr 11 | fnWinVerifyTrust uintptr 12 | ) 13 | 14 | func init() { 15 | libwintrust, _ = syscall.LoadLibrary("wintrust.dll") 16 | fnWinLoadTrustProvider, _ = syscall.GetProcAddress(libwintrust, "WinLoadTrustProvider") 17 | fnWinSubmitCertificate, _ = syscall.GetProcAddress(libwintrust, "WinSubmitCertificate") 18 | fnWinVerifyTrust, _ = syscall.GetProcAddress(libwintrust, "WinVerifyTrust") 19 | } 20 | -------------------------------------------------------------------------------- /WinApi/wtsapi32.go: -------------------------------------------------------------------------------- 1 | package WinApi 2 | 3 | import ( 4 | "syscall" 5 | ) 6 | 7 | var ( 8 | libwtsapi32 syscall.Handle 9 | fnWTSRegisterSessionNotification uintptr 10 | fnWTSUnRegisterSessionNotification uintptr 11 | ) 12 | 13 | func init() { 14 | libwtsapi32, _ = syscall.LoadLibrary("wtsapi32.dll") 15 | if libwtsapi32 == 0 { 16 | return 17 | } 18 | fnWTSRegisterSessionNotification, _ = syscall.GetProcAddress(libwtsapi32, "WTSRegisterSessionNotification") 19 | fnWTSUnRegisterSessionNotification, _ = syscall.GetProcAddress(libwtsapi32, "WTSUnRegisterSessionNotification") 20 | } 21 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/suiyunonghen/GVCL 2 | 3 | go 1.12 4 | 5 | require ( 6 | github.com/suiyunonghen/DxCommonLib v0.5.2 7 | golang.org/x/image v0.1.0 8 | ) 9 | 10 | replace ( 11 | //github.com/suiyunonghen/DxCommonLib => /../DxCommonLib 12 | golang.org/x/crypto => github.com/golang/crypto v0.2.0 13 | golang.org/x/image => github.com/golang/image v0.1.0 14 | golang.org/x/net => github.com/golang/net v0.2.0 15 | golang.org/x/sync => github.com/golang/sync v0.1.0 16 | golang.org/x/sys => github.com/golang/sys v0.2.0 17 | golang.org/x/text => github.com/golang/text v0.4.0 18 | golang.org/x/tools => github.com/golang/tools v0.3.0 19 | golang.org/x/xerrors => github.com/golang/xerrors v0.0.0-20220907171357-04be3eba64a2 20 | ) 21 | -------------------------------------------------------------------------------- /test/Dota2.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/suiyunonghen/GVCL/7eda51bafb141c506b3f87b18ac6ed91f662ce35/test/Dota2.ico -------------------------------------------------------------------------------- /test/GVCL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/suiyunonghen/GVCL/7eda51bafb141c506b3f87b18ac6ed91f662ce35/test/GVCL.png -------------------------------------------------------------------------------- /test/PngUi.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/suiyunonghen/GVCL/Components/Controls" 5 | "github.com/suiyunonghen/GVCL/WinApi" 6 | "github.com/suiyunonghen/GVCL/Graphics" 7 | "github.com/suiyunonghen/DxCommonLib" 8 | "time" 9 | ) 10 | 11 | func PngUi(frm *controls.GForm) { 12 | var BlendFunction WinApi.BLENDFUNCTION 13 | DxCommonLib.Sleep(time.Second) 14 | BlendFunction.BlendOp = WinApi.AC_SRC_OVER 15 | BlendFunction.BlendFlags = 0 16 | BlendFunction.SourceConstantAlpha = 255 17 | BlendFunction.AlphaFormat = WinApi.AC_SRC_ALPHA 18 | 19 | handle := frm.GetWindowHandle() 20 | dc := WinApi.GetDC(handle) 21 | ptDst := WinApi.POINT{frm.Left(),frm.Top()} 22 | frm.SetWidth(632) 23 | frm.SetHeight(643) 24 | osize := WinApi.GSize{632,643} 25 | ptSrc := WinApi.POINT{} 26 | WinApi.SetWindowLong(handle,WinApi.GWL_STYLE,WinApi.GetWindowLong(handle,WinApi.GWL_STYLE) & (^WinApi.WS_CAPTION) & (^WinApi.WS_THICKFRAME)) 27 | WinApi.SetWindowLong(handle,WinApi.GWL_EXSTYLE,WinApi.GetWindowLong(handle, WinApi.GWL_EXSTYLE) | WinApi.WS_EX_LAYERED) 28 | var tmpbmp Graphics.GBitmap 29 | 30 | //str = "" 31 | for i := 1;i<=1;i++{ 32 | /*if i < 9{ 33 | str= fmt.Sprintf(`E:\Delphi\SuperTech\TJDun\LocalServer\Res\00%d.png`,i) 34 | }else{ 35 | str = fmt.Sprintf(`E:\Delphi\SuperTech\TJDun\LocalServer\Res\0%d.png`,i) 36 | }*/ 37 | str := `e:\2.png` 38 | tmpbmp.LoadFromFile(str) 39 | 40 | //var destbmp Graphics.GBitmap 41 | //destbmp.SetSize(int(frm.Width()),int(frm.Height()),true) 42 | //cvs := destbmp.Canvas() 43 | //cvs.Draw(0,0,&tmpbmp) 44 | WinApi.UpdateLayeredWindow(handle,dc,&ptDst,&osize,tmpbmp.Canvas().GetHandle(),&ptSrc,0,&BlendFunction,WinApi.ULW_ALPHA) 45 | //destbmp.Free() 46 | DxCommonLib.Sleep(100) 47 | } 48 | WinApi.ReleaseDC(handle,dc) 49 | } 50 | 51 | func main() { 52 | app := controls.NewApplication() 53 | m := app.CreateForm() 54 | m.SetLeft(200) 55 | m.SetTop(50) 56 | //m.SetWidth(650) 57 | //m.SetHeight(650) 58 | m.SetCaption("测试窗体") 59 | 60 | 61 | 62 | 63 | go PngUi(m) 64 | 65 | app.Run() 66 | } -------------------------------------------------------------------------------- /test/buildrc.bat: -------------------------------------------------------------------------------- 1 | @REM @Author: anchen 2 | @REM @Date: 2016-09-14 09:58:47 3 | @REM @Last Modified by: anchen 4 | @REM Modified time: 2016-09-14 11:50:23 5 | @REM rsrc.exe -ico="dota.ico,Dota2.ico" -manifest msgbox.manifest -bmp GVCL.bmp -o msgbox.syso 6 | @REM syso -o msgbox.syso 7 | rsrc.exe -ico="dota.ico,Dota2.ico" -manifest msgbox.manifest -bmp GVCL.bmp -o msgbox.syso 8 | go build -ldflags="-H windowsgui" 9 | @REM go build -------------------------------------------------------------------------------- /test/dota.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/suiyunonghen/GVCL/7eda51bafb141c506b3f87b18ac6ed91f662ce35/test/dota.ico -------------------------------------------------------------------------------- /test/msgbox.exe.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /test/msgbox.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | _ "fmt" 6 | "github.com/suiyunonghen/DxCommonLib" 7 | _ "github.com/suiyunonghen/GVCL/Components" 8 | "github.com/suiyunonghen/GVCL/Components/Controls" 9 | "github.com/suiyunonghen/GVCL/Components/DxControls/Scintilla" 10 | "github.com/suiyunonghen/GVCL/Components/DxControls/WindowLessControls" 11 | "github.com/suiyunonghen/GVCL/Components/DxControls/gminiblink" 12 | "github.com/suiyunonghen/GVCL/Components/NVisbleControls" 13 | "github.com/suiyunonghen/GVCL/Graphics" 14 | _ "github.com/suiyunonghen/GVCL/Graphics" 15 | "github.com/suiyunonghen/GVCL/WinApi" 16 | _ "github.com/suiyunonghen/GVCL/WinApi" 17 | _ "reflect" 18 | _ "time" 19 | ) 20 | 21 | type GForm1 struct { 22 | controls.GForm 23 | Button1 *controls.GButton 24 | Edit1 *Scintilla.GScintilla 25 | } 26 | 27 | func NewForm1(app *controls.WApplication) *GForm1 { 28 | frm := new(GForm1) 29 | frm.SubInit() 30 | frm.Button1 = controls.NewButton(frm) 31 | frm.Button1.SetWidth(80) 32 | frm.Button1.SetHeight(30) 33 | frm.Button1.SetCaption("确定关闭") 34 | 35 | frm.Edit1 = Scintilla.NewScintillaEditor(frm) 36 | frm.Edit1.SetColor(Graphics.RGB(184, 220, 220)) 37 | frm.Edit1.MarginBand.ShowCodeFlod = true 38 | 39 | pop := NVisbleControls.NewPopupMenu(frm) 40 | TargetBookmarkItem := pop.Items().AddItem("设置书签") 41 | GotoBookmarkItem := pop.Items().AddItem("跳转书签") 42 | for i := 0; i < 10; i++ { 43 | str := fmt.Sprintf("%s%d", "书签", i) 44 | bookmarkitem := TargetBookmarkItem.AddItem(str) 45 | bookmarkitem.TagData = i 46 | bookmarkitem.OnClick = func(sender interface{}) { 47 | frm.Edit1.MarginBand.SetBookmark(sender.(*NVisbleControls.GMenuItem).TagData.(int)) 48 | } 49 | gotobookitem := GotoBookmarkItem.AddItem(str) 50 | gotobookitem.TagData = i 51 | gotobookitem.OnClick = func(sender interface{}) { 52 | frm.Edit1.MarginBand.GotoBookmark(sender.(*NVisbleControls.GMenuItem).TagData.(int)) 53 | } 54 | } 55 | GotoBookmarkItem = pop.Items().AddItem("清空所有书签") 56 | GotoBookmarkItem.OnClick = func(sender interface{}) { 57 | frm.Edit1.MarginBand.ClearMarks() 58 | } 59 | frm.Edit1.PopupMenu = pop 60 | 61 | frm.Edit1.CodeLines.LineBreak = DxCommonLib.LBK_CRLF 62 | frm.Edit1.CodeLines.LoadFromFile("D:\\bookmarks.html") 63 | //("J:\\GoLibrary\\src\\github.com\\suiyunonghen\\GVCL\\Components\\componentCore.go") 64 | 65 | lexer := Scintilla.NewHtmlLexer() 66 | frm.Edit1.SetLexer(lexer) 67 | frm.OnClose = func(sender interface{}, closeAction *int8) { 68 | *closeAction = controls.CAFree 69 | } 70 | frm.OnResize = func(sender interface{}) { 71 | frm.Button1.SetLeft(frm.Width() - 90) 72 | frm.Button1.SetTop(frm.Height() - 80) 73 | frm.Edit1.SetWidth(frm.Width() - 20) 74 | frm.Edit1.SetHeight(frm.Height() - 80) 75 | } 76 | frm.Button1.OnClick = func(sender interface{}) { 77 | str := frm.Edit1.CodeLines.Strings(0) 78 | WinApi.MessageBox(frm.GetWindowHandle(), "测试", str, 64) 79 | frm.Edit1.CodeLines.SetStrings(0, "不得闲测试") 80 | } 81 | return frm 82 | } 83 | 84 | type GForm2 struct { 85 | controls.GForm 86 | Browser *gminiblink.GBlinkWebBrowser 87 | } 88 | 89 | func NewForm2(app *controls.WApplication) *GForm2 { 90 | 91 | frm := new(GForm2) 92 | frm.SubInit() 93 | frm.Browser = gminiblink.NewBlinkWebBrowser(frm, BindFunctions) 94 | frm.OnShow = func(sender interface{}) { 95 | //frm.Browser.Navigate("www.baidu.com") 96 | frm.Browser.LoadFromFile(0, `E:\GoLib\src\github.com\suiyunonghen\GVCL\Components\DxControls\gminiblink\test.html`) 97 | } 98 | frm.OnClose = func(sender interface{}, closAction *int8) { 99 | *closAction = controls.CAFree 100 | } 101 | frm.OnResize = func(sender interface{}) { 102 | r := frm.ClientRect() 103 | frm.Browser.SetWidth(r.Width()) 104 | frm.Browser.SetHeight(r.Height()) 105 | } 106 | frm.Browser.OnConsole = func(webView gminiblink.WkeWebView, level gminiblink.WkeConsoleLevel, msg, sourceName string, sourceline uint32, stackTrace string) { 107 | fmt.Println(level) 108 | fmt.Println("ConsoleMsg:", msg) 109 | fmt.Println("ConsolesourceName:", sourceName, ",sourceline:", sourceline) 110 | fmt.Println("stackTrace:", stackTrace) 111 | } 112 | frm.Browser.OnDocumentCompleted = func(sender interface{}) { 113 | htmlinterface := frm.Browser.JsCallGlobal("JsHtml") 114 | WinApi.MessageBox(frm.GetWindowHandle(), "页面加载完成,调用内部JS获取网页源码\r\n"+htmlinterface.(string), "Html源码", 64) 115 | 116 | } 117 | return frm 118 | } 119 | 120 | var ( 121 | BindFunctions map[string]*gminiblink.JSBindFunction 122 | ) 123 | 124 | func main() { 125 | 126 | /*gminiblink.BlinkLib.LoadBlink(`E:\GoLib\miniblink64_20190810\miniblink64\node.dll`) 127 | wv := gminiblink.BlinkLib.WkeCreateWebWindow(gminiblink.WKE_WINDOW_TYPE_POPUP, 0, 0, 0, 640, 480) 128 | gminiblink.BlinkLib.WkeShowWindow(wv, true) 129 | gminiblink.BlinkLib.WkeLoadURL(wv, "https://www.baidu.com") 130 | 131 | msg := new(WinApi.MSG) 132 | for { 133 | if msg.PeekMessage(0, 0, 0, WinApi.PM_REMOVE) { 134 | if msg.Message != WinApi.WM_TIMER { 135 | fmt.Println(msg.Message) 136 | } 137 | if msg.Message == WinApi.WM_QUIT { 138 | break 139 | } 140 | msg.TranslateMessage() 141 | msg.DispatchMessage() 142 | } else { 143 | WinApi.WaitMessage() 144 | } 145 | } 146 | return*/ 147 | 148 | app := controls.NewApplication() 149 | m := app.CreateForm() 150 | m.SetLeft(200) 151 | m.SetTop(50) 152 | m.SetCaption("测试窗体") 153 | 154 | lbl := controls.NewLabel(m) 155 | lbl.SetCaption("说明 ") 156 | lbl.SetTrasparent(true) 157 | 158 | //lbl.SetAutoSize(true) 159 | lbl.SetColor(Graphics.ClRed) 160 | lbl.SetTop(40) 161 | 162 | b1 := controls.NewButton(m) 163 | b1.SetCaption("关闭") 164 | b1.Font.BeginUpdate() 165 | b1.Font.SetSize(10) 166 | b1.Font.Underline = 1 167 | b1.Font.SetBold(true) 168 | b1.Font.EndUpdate() 169 | b1.SetLeft(100) 170 | b1.SetTop(40) 171 | 172 | cmb := controls.NewCombobox(m, controls.CSDropDownList) 173 | cmb.SetTop(80) 174 | cmb.SetLeft(180) 175 | listitems := cmb.Items() 176 | for i := 0; i < 10; i++ { 177 | listitems.Add("asfasf") 178 | listitems.Add("测试二恶") 179 | } 180 | cmb.SetItemIndex(1) 181 | 182 | app.Run() 183 | return 184 | 185 | BindFunctions = make(map[string]*gminiblink.JSBindFunction) 186 | func1 := new(gminiblink.JSBindFunction) 187 | func1.BindHandle = func(params ...interface{}) interface{} { 188 | h := app.MainForm().GetWindowHandle() 189 | WinApi.MessageBox(h, params[0].(string), "Go内部函数", 64) 190 | return 0 191 | } 192 | func1.ParamCount = 1 193 | BindFunctions["GoMsgBox"] = func1 194 | 195 | func1 = new(gminiblink.JSBindFunction) 196 | func1.BindHandle = func(params ...interface{}) interface{} { 197 | sum := 0 198 | for _, v := range params { 199 | sum += v.(int) 200 | } 201 | return sum 202 | } 203 | func1.ParamCount = 0 204 | BindFunctions["Gosum"] = func1 205 | 206 | //菜单 207 | pop := NVisbleControls.NewPopupMenu(m) 208 | tmpitem := pop.Items().AddItem("测试1") 209 | citem := tmpitem.AddItem("子测试1") 210 | citem.OnClick = func(sender interface{}) { 211 | if fileVersion, _, ok := WinApi.GetProductVersion("D:\\DevTools\\Microsoft VS Code\\Code.exe"); ok { 212 | 213 | st := fmt.Sprintf("%d.%d.%d", fileVersion.Major, fileVersion.Minor, fileVersion.Build) 214 | WinApi.MessageBox(m.GetWindowHandle(), st+sender.(*NVisbleControls.GMenuItem).Caption(), "消息", 64) 215 | } else { 216 | WinApi.MessageBox(m.GetWindowHandle(), "菜单测试"+sender.(*NVisbleControls.GMenuItem).Caption(), "消息", 64) 217 | } 218 | } 219 | citem = pop.Items().AddItem("注册表") 220 | citem.OnClick = func(sender interface{}) { 221 | reg := NVisbleControls.NewRegistry(0) 222 | reg.SetRootKey(WinApi.HKEY_LOCAL_MACHINE) 223 | if reg.OpenKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", false) { 224 | if reg.ValueExists("SynTPEnh") { 225 | WinApi.MessageBox(m.GetWindowHandle(), "SynTPEnh自动启动: "+reg.ReadString("SynTPEnh"), "消息", 64) 226 | } 227 | WinApi.MessageBox(m.GetWindowHandle(), "打开注册表测试"+sender.(*NVisbleControls.GMenuItem).Caption(), "消息", 64) 228 | } 229 | reg.Free() 230 | } 231 | 232 | //托盘图标 233 | icon := NVisbleControls.NewTrayIcon(m) 234 | icon.SetIcon(app.AppIcon()) 235 | //icon.SetIcon(WinApi.LoadIcon(controls.Hinstance,uintptr(5))) 236 | icon.SetVisible(true) 237 | icon.PopupMenu = pop 238 | icon.OnDblClick = func(sender interface{}) { 239 | if !m.Visible() { 240 | m.Show() 241 | } else { 242 | m.SetVisible(false) 243 | } 244 | } 245 | 246 | m.PopupMenu = pop 247 | 248 | e := controls.NewEdit(m) 249 | e.SetName("Edit1") 250 | e.SetLeft(10) 251 | e.SetWidth(100) 252 | e.SetHeight(20) 253 | e.SetCaption("测试") 254 | b := controls.NewButton(m) 255 | b.SetDefault(true) 256 | b.SetLeft(120) 257 | b.SetCaption("创建窗体") 258 | b.OnClick = func(sender interface{}) { 259 | tmpm := NewForm1(app) 260 | tmpm.SetCaption(e.GetText()) 261 | if tmpm.ShowModal() == controls.MrOK { 262 | WinApi.MessageBox(tmpm.GetWindowHandle(), "程序确定退出", "消息", 64) 263 | } 264 | 265 | } 266 | 267 | bBrowser := controls.NewButton(m) 268 | bBrowser.SetLeft(240) 269 | bBrowser.SetCaption("miniBlink") 270 | bBrowser.OnClick = func(sender interface{}) { 271 | tmpm := NewForm2(app) 272 | tmpm.SetCaption("测试MiniBlink") 273 | tmpm.ShowModal() 274 | } 275 | 276 | b1 = controls.NewButton(m) 277 | b1.SetCaption("关闭") 278 | b1.Font.BeginUpdate() 279 | b1.Font.SetSize(10) 280 | b1.Font.Underline = 1 281 | b1.Font.SetBold(true) 282 | b1.Font.EndUpdate() 283 | b1.SetLeft(100) 284 | b1.SetTop(40) 285 | 286 | lstBox := controls.NewListBox(m) 287 | lstBox.SetTop(80) 288 | lstBox.SetLeft(40) 289 | //lstBox.SetWidth(200) 290 | //lstBox.SetHeight(200) 291 | listitems = lstBox.Items() 292 | listitems.Add("asfasf") 293 | listitems.Add("测试二恶") 294 | 295 | lstBox.OnItemDblClick = func(sender interface{}) { 296 | mb := sender.(*controls.GListBox) 297 | WinApi.MessageBox(mb.GetWindowHandle(), mb.Items().Strings(mb.GetItemIndex()), "消息", 64) 298 | } 299 | 300 | checkbox := WindowLessControls.NewCheckBox(m) 301 | checkbox.SetLeft(lbl.Left() + 10) 302 | checkbox.SetTop(lstBox.Top() + lstBox.Height() + 10) 303 | checkbox.SetCaption("测试选择框") 304 | checkbox.SetChecked(true) 305 | 306 | b1.OnClick = func(sender interface{}) { 307 | /*cvs := new(controls.GControlCanvas) 308 | cvs.SubInit() 309 | cvs.SetControl(m) 310 | brsh := cvs.Brush() 311 | brsh.Color = Graphics.ClRed 312 | brsh.BrushStyle = Graphics.BSCross 313 | brsh.Change() 314 | r := new(WinApi.Rect) 315 | r.Left = 20 316 | r.Top = 20 317 | r.Right = 150 318 | r.Bottom = 150 319 | cvs.FillRect(r)*/ 320 | lstBox.Font.BeginUpdate() 321 | lstBox.Font.SetName("宋体") 322 | lstBox.Font.SetBold(true) 323 | lstBox.Font.EndUpdate() 324 | 325 | lbl.Font.BeginUpdate() 326 | lbl.Font.Italic = 1 327 | lbl.Font.SetBold(true) 328 | lbl.Font.EndUpdate() 329 | } 330 | 331 | app.Run() 332 | } 333 | -------------------------------------------------------------------------------- /test/msgbox.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /test/msgbox.syso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/suiyunonghen/GVCL/7eda51bafb141c506b3f87b18ac6ed91f662ce35/test/msgbox.syso -------------------------------------------------------------------------------- /test/testDraw.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/suiyunonghen/GVCL/Components/Controls" 5 | "github.com/suiyunonghen/GVCL/WinApi" 6 | "image" 7 | "unsafe" 8 | "os" 9 | "image/png" 10 | "github.com/suiyunonghen/GVCL/Graphics" 11 | "fmt" 12 | "github.com/suiyunonghen/GVCL/Components/DxControls/WindowLessControls" 13 | "time" 14 | ) 15 | 16 | func main() { 17 | app := controls.NewApplication() 18 | m := app.CreateForm() 19 | m.SetLeft(200) 20 | m.SetTop(50) 21 | m.SetCaption("测试窗体") 22 | m.SetColor(Graphics.ClGreen) 23 | 24 | 25 | img := WindowLessControls.NewImage(m,Graphics.GDS_NORMAL) 26 | img.Picture.LoadFromFile(`E:\Delphi\SuperTech\TJDun\LocalServer\Res\001.png`) 27 | img.SetLeft(20) 28 | img.SetTop(20) 29 | img.SetWidth(400) 30 | img.SetHeight(400) 31 | 32 | btn := controls.NewButton(m) 33 | btn.SetCaption("画图") 34 | btn.OnClick = func(sender interface{}) { 35 | //f,_ := os.Open("E:\\1.bmp") 36 | f,_ := os.Open(`E:\Delphi\Leigod\LeigodAccelerator_Windows_New\qimiao\res\myinfoimg.png`) 37 | img,_ := png.Decode(f) 38 | f.Close() 39 | //绘图 40 | var m_pBmiPaint WinApi.BITMAPINFO 41 | //memdc := WinApi.CreateCompatibleDC(WinApi.GetDC(m.GetWindowHandle())) 42 | rgba := img.(*image.NRGBA) 43 | m_pBmiPaint.BmiHeader.BiBitCount = 32 44 | m_pBmiPaint.BmiHeader.BiClrImportant = 0 45 | m_pBmiPaint.BmiHeader.BiClrUsed = 0 46 | m_pBmiPaint.BmiHeader.BiCompression = WinApi.BI_RGB 47 | m_pBmiPaint.BmiHeader.BiHeight = int32(rgba.Rect.Max.Y - rgba.Rect.Min.Y) 48 | m_pBmiPaint.BmiHeader.BiPlanes = 1 49 | m_pBmiPaint.BmiHeader.BiWidth = int32(rgba.Rect.Max.X - rgba.Rect.Min.X) 50 | m_pBmiPaint.BmiHeader.BiXPelsPerMeter = 39 51 | m_pBmiPaint.BmiHeader.BiYPelsPerMeter = 39 52 | m_pBmiPaint.BmiHeader.BiSizeImage = uint32(len(rgba.Pix)) 53 | m_pBmiPaint.BmiHeader.BiSize =uint32(unsafe.Sizeof(WinApi.BITMAPINFOHEADER{})) 54 | memdc := WinApi.GetDC(m.GetWindowHandle()) 55 | //因为是倒着的,所以恢复对掉一下上下位置 56 | /*mb := make([]byte,m_pBmiPaint.BmiHeader.BiSizeImage) 57 | lastp := len(mb) 58 | for h := 0;h<252;h++{ 59 | tmpb := mb[(251-h)*272*4:lastp] 60 | for w := 0;w<272*4;w++{ 61 | tmpb[w] = rgba.Pix[h*272*4+w] 62 | } 63 | lastp = (251-h)*272*4 64 | }*/ 65 | //lastp := len(rgba.Pix) 66 | for h := 0;h