编译:nim c --app:gui hello.nim 后者有控制台的: nim c hello.nim
关于使用vs 作为nim生成C代码的编译器,上篇博客中说过。
nim 和 C太像了,感觉就像C的语法糖。
下面看代码:
import
windows
#{.link:"hello.res".}
const
IDI_TEST_GUI = 107
IDC_TEST_GUI = 109
proc MakeIntResource(id:int):LPCSTR =
cast[LPSTR](id)
type
MyWnd = object
hWnd*:HWND
method `hWnd=`*(this:var MyWnd,value:HWND) =
this.hWnd = value
method hWnd*(this:var MyWnd) :HWND = this.hWnd
var g_wnd : MyWnd = MyWnd()
var tls_index : DWORD = 0
let instance = GetModuleHandle(nil)
var
hbmp : HBITMAP
Bkbmp: BITMAP
proc Init(): bool =
hbmp = LoadImage(instance,r"1.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE)
if hbmp !=0 :
let ret = GetObject(cast[HGDIOBJ](hbmp),cast[int32](sizeof(BITMAP)),cast[LPVOID](addr Bkbmp))
if ret!=1 :
return true
else:
echo "LoadImage failed"
return false
proc OnPaint(hwnd:HWND) :LRESULT {.stdcall.} =
var ps:PAINTSTRUCT
let hdc = BeginPaint(hwnd,ps)
var rt : RECT
discard GetClientRect(hwnd,rt)
let hb = CreateSolidBrush(0x00ff00ff)
discard FillRect(hdc,rt,hb)
discard Rectangle(hdc,10,10,100,100)
discard DeleteObject(hb)
let memdc = CreateCompatibleDC(hdc)
let hbmp = LoadImage(instance,r"1.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE)
let old = SelectObject(memdc,hbmp)
discard Bitblt(hdc,0,0,rt.BottomRight.x,rt.BottomRight.y,memdc,0,0,SRCCOPY)
discard SelectObject(memdc,old)
discard DeleteObject(hbmp)
discard DeleteDC(memdc)
discard EndPaint(hwnd,ps)
proc mywndproc(hwnd:HWND,msg:WINUINT,wParam:WPARAM,lParam:LPARAM) : LRESULT {.stdcall.} =
case msg:
of WM_CREATE:
var
hmenu:HMENU
info :MENUITEMINFO
hsubmenu:HMENU
let hicon = LoadImage(0,"nim.ico",IMAGE_ICON,0,0,LR_LOADFROMFILE)
discard SetClassLong(hwnd,GCL_HICON,cast[LONG](hicon))
hmenu = CreateMenu()
info.cbSize = 44
info.fMask = MIIM_STRING or MIIM_ID
info.fType = MFT_STRING
info.wID = 100
info.cch = 4
info.dwTypeData = "test"
info.hbmpItem = 0
if InsertMenuItem(hmenu,0,0,addr(info)) !=1 :
echo "InsertMenu failed=",GetLastError()
info.wID=101
info.cch=4
info.dwTypeData = "Help"
#discard InsertMenuItem(hmenu,1,0,addr(info))
info.wID = 102
info.fMask = MIIM_SUBMENU or MIIM_STRING
hsubmenu = CreatePopupMenu()
info.hSubMenu = hsubmenu
if InsertMenu(hsubmenu,0,MF_BYCOMMAND,100,"test")!=1 :
echo "InsertMenu err=",GetLastError()
discard InsertMenu(hsubmenu,0,MF_BYCOMMAND,100,"exit")
discard InsertMenu(hsubmenu,0,MF_BYCOMMAND,100,"about")
discard InsertMenuItem(hmenu,2,0,addr(info))
#discard InsertMenu(hmenu,0,MF_BYCOMMAND,100,"test")
#discard InsertMenu(hmenu,0,MF_BYCOMMAND,101,"file")
discard SetMenu(hwnd,hmenu)
var mywnd = cast[ptr MyWnd](TlsGetValue(tls_index))
mywnd.hWnd = hwnd
echo "WM_CREATE enter",hwnd
return 1
of WM_PAINT:
discard OnPaint(hwnd)
return 1
of WM_CLOSE:
#discard MessageBox(0,"close","msg",0)
discard DestroyWindow(hwnd)
of WM_DESTROY:
#discard MessageBox(0,"DestroyWindow:","msg",0)
PostQuitMessage(WM_QUIT)
else:discard
return DefWindowProc(hwnd,msg,wParam,lParam)
proc MyRegisterWindow():ATOM =
var wnd_cls : WNDCLASSEX
wnd_cls.cbSize =cast[WINUINT](sizeof(WNDCLASSEX))
wnd_cls.cbClsExtra = 0
wnd_cls.cbWndExtra = 0
wnd_cls.hInstance = instance
wnd_cls.hIcon = LoadIcon(instance,IDI_HAND)
wnd_cls.hCursor = LoadCursor(0,IDC_ARROW)
wnd_cls.hbrBackground = COLOR_WINDOW+1
wnd_cls.lpszMenuName = nil
wnd_cls.lpszClassName = r"haha"
wnd_cls.lpfnWndProc = mywndproc
wnd_cls.style = CS_HREDRAW or CS_VREDRAW
RegisterClassEx(wnd_cls)
proc InitWindow() : HWND =
var style:DWORD = 0
var cls_name = r"haha"
var caption : cstring = r"hello"
var
x,y,width,height:DWORD
x = 0
y = 0
width = Bkbmp.bmWidth
height = Bkbmp.bmHeight
var parent:HWND = 0
var menu:HMENU =0
var creat_param : LPVOID = nil
tls_index = TlsAlloc()
if tls_index==0xffffffff:quit(1)
discard TlsSetValue(tls_index,addr(g_wnd))
let hwnd = CreateWindowEx(style,cls_name,caption,
WS_OVERLAPPEDWINDOW,x,y,width,height,parent,menu,instance,creat_param)
if hwnd == 0:
let err = GetLastError()
discard MessageBox(0,"createwindowex error:" & $err,"msg",0)
#echo "createwindowex error:",GetLastError()
else:
g_wnd.hWnd = hwnd
discard ShowWindow(hwnd,SW_SHOW)
discard UpdateWindow(hwnd)
result = hwnd
proc main() =
if not Init():
quit(0)
let ret = MyRegisterWindow()
if ret != 0 :
if InitWindow() == 0 :
quit(0)
var msg : MSG
while GetMessageW(msg,0,0,0)!=0:
discard TranslateMessage(msg)
discard DispatchMessage(msg)
else:
echo "RegisterClass failed"
main()
自己随便找了张图片,生成如下:
使用windows API 的时候如果哪个API 在windows.nim 中没有,那么自己参考windows.nim 声明一下就可以了。还有enum , 常量,结构体都有对应的元素。