Author Topic: winim  (Read 330 times)

Offline John

  • Forum Support / SB Dev
  • Posts: 2973
    • ScriptBasic Open Source Project
winim
« on: January 03, 2020, 07:56:41 PM »
I discovered a very well done Windows API Nim package that even has COM/OLE support.

Nim's Windows API and COM Library

Line Demo
Code: Text
  1. #====================================================================
  2. #
  3. #               Winim - Nim's Windows API Module
  4. #                 (c) Copyright 2016-2019 Ward
  5. #====================================================================
  6.  
  7. import winim/lean
  8.  
  9. proc WindowProc(hwnd: HWND, message: UINT, wParam: WPARAM, lParam: LPARAM): LRESULT {.stdcall.} =
  10.   var
  11.     cxClient {.global.}: DWORD
  12.     cyClient {.global.}: DWORD
  13.  
  14.   case message
  15.   of WM_SIZE:
  16.     cxClient = DWORD LOWORD(lParam)
  17.     cyClient = DWORD HIWORD(lParam)
  18.     return 0
  19.  
  20.   of WM_PAINT:
  21.     var ps: PAINTSTRUCT
  22.     var hdc = BeginPaint(hwnd, ps)
  23.     defer: EndPaint(hwnd, ps)
  24.  
  25.     Rectangle(hdc, cxClient div 8, cyClient div 8, 7 * cxClient div 8, 7 * cyClient div 8)
  26.  
  27.     MoveToEx(hdc, 0, 0, NULL)
  28.     LineTo(hdc, cxClient, cyClient)
  29.  
  30.     MoveToEx(hdc, 0, cyClient, NULL)
  31.     LineTo(hdc, cxClient, 0)
  32.  
  33.     Ellipse(hdc, cxClient div 8, cyClient div 8, 7 * cxClient div 8, 7 * cyClient div 8)
  34.     RoundRect(hdc, cxClient div 4, cyClient div 4, 3 * cxClient div 4, 3 * cyClient div 4, cxClient div 4, cyClient div 4)
  35.     return 0
  36.  
  37.   of WM_DESTROY:
  38.     PostQuitMessage(0)
  39.     return 0
  40.  
  41.   else:
  42.     return DefWindowProc(hwnd, message, wParam, lParam)
  43.  
  44. proc main() =
  45.   var
  46.     hInstance = GetModuleHandle(nil)
  47.     appName = "LineDemo"
  48.     hwnd: HWND
  49.     msg: MSG
  50.     wndclass: WNDCLASS
  51.  
  52.   wndclass.style = CS_HREDRAW or CS_VREDRAW
  53.   wndclass.lpfnWndProc = WindowProc
  54.   wndclass.cbClsExtra = 0
  55.   wndclass.cbWndExtra = 0
  56.   wndclass.hInstance = hInstance
  57.   wndclass.hIcon = LoadIcon(0, IDI_APPLICATION)
  58.   wndclass.hCursor = LoadCursor(0, IDC_ARROW)
  59.   wndclass.hbrBackground = GetStockObject(WHITE_BRUSH)
  60.   wndclass.lpszMenuName = nil
  61.   wndclass.lpszClassName = appName
  62.  
  63.   if RegisterClass(wndclass) == 0:
  64.     MessageBox(0, "This program requires Windows NT!", appName, MB_ICONERROR)
  65.     return
  66.  
  67.   hwnd = CreateWindow(appName, "Line Demonstration", WS_OVERLAPPEDWINDOW,
  68.     CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  69.     0, 0, hInstance, nil)
  70.  
  71.   ShowWindow(hwnd, SW_SHOW)
  72.   UpdateWindow(hwnd)
  73.  
  74.   while GetMessage(msg, 0, 0, 0) != 0:
  75.     TranslateMessage(msg)
  76.     DispatchMessage(msg)
  77.  
  78. main()
  79.  

Offline John

  • Forum Support / SB Dev
  • Posts: 2973
    • ScriptBasic Open Source Project
Re: winim
« Reply #1 on: January 04, 2020, 12:35:42 PM »
I was able to test the COM functionality of the winim library unsing Excel as my COM object.

Code: Text
  1. import strutils
  2. import winim.com
  3.  
  4. comScript:
  5.   var obj = CreateObject("Excel.Application")
  6.   obj.visible = true
  7.   obj.workbooks.add()
  8.  
  9.   var
  10.     s1 = "the quick fox jumps over the lazy brown dog".split(" ")
  11.     s2 = @[@[1, 2], @[3, 4, 5, 6, 7], @[8, 9, 10, 11], @[12], @[13, 14, 15]]
  12.  
  13.   obj.activeSheet.range("A1:E6").clear()
  14.   obj.activeSheet.range("A1:I1") = s1 # this convert seq to 1D safearray
  15.   obj.activeSheet.range("A2:E6") = s2 # this convert seq to 2D safearray
  16.  
  17.   # obj.activeSheet.saveAs("jrs.xls")
  18.   # obj.activeSheet.close(0)
  19.  
  20.   COM_FullRelease()
  21.  


Offline John

  • Forum Support / SB Dev
  • Posts: 2973
    • ScriptBasic Open Source Project
Re: winim
« Reply #2 on: January 04, 2020, 05:12:26 PM »
One of my concerns rebuilding my toolbox with Nim was COM/OLE (CallbyName) support. I'm happy to say that concern is behind me. I do a lot of interface work with QuickBooks Enterprise which uses a COM SDK as their interface. Here is an example of a ScriptBasic and Nim script to return the CoA. (Chart of Accounts)

Code: Script BASIC
  1. IMPORT COM.sbi
  2.  
  3. oqbXMLRP = COM::CREATE(:SET, "QBFC13.QBSessionManager.1")
  4.  
  5. COM::CBN(oqbXMLRP, "OpenConnection", :CALL, "", "ScriptBasic")
  6. COM::CBN(oqbXMLRP, "BeginSession", :CALL, "", 2)
  7.  
  8. xml_request = """
  9. <?qbxml version="13.0"?>
  10. <QBXML>
  11.   <QBXMLMsgsRq onError="stopOnError">
  12.     <AccountQueryRq>
  13.     </AccountQueryRq>
  14.   </QBXMLMsgsRq>
  15. </QBXML>
  16. """
  17.  
  18. oResponse = COM::CBN(oqbXMLRP, "DoRequestsFromXMLString", :CALL, xml_request)
  19. xml_str = COM::CBN(oResponse, "ToXMLString", :CALL)
  20.  
  21. PRINT xml_str,"\n"
  22.  
  23. COM::CBN(oqbXMLRP, "EndSession", :CALL)
  24. COM::CBN(oqbXMLRP, "CloseConnection", :CALL)
  25. COM::RELEASE(oResponse)
  26. COM::RELEASE(oqbXMLRP)
  27.  

Nim
Code: Text
  1. import winim.com
  2.  
  3. comScript:
  4.  
  5.   var xml_request = """
  6.   <?qbxml version="13.0"?>
  7.   <QBXML>
  8.     <QBXMLMsgsRq onError="stopOnError">
  9.       <AccountQueryRq>
  10.       </AccountQueryRq>
  11.     </QBXMLMsgsRq>
  12.   </QBXML>
  13.   """
  14.   var qbobj = CreateObject("QBFC13.QBSessionManager.1")
  15.  
  16.   qbobj.OpenConnection("", "Nim")
  17.   qbobj.BeginSession("", 2)
  18.  
  19.   var oResponse = qbobj.DoRequestsFromXMLString(xml_request)
  20.   var xml_str = oResponse.ToXMLString()  
  21.    
  22.   echo xml_str
  23.  
  24.   qbobj.EndSession()
  25.   qbobj.CloseConnection()
  26.  
  27.   COM_FullRelease()
  28.  


Attached is the response from this request using a QB demo company.
« Last Edit: January 04, 2020, 05:15:50 PM by John »

Offline John

  • Forum Support / SB Dev
  • Posts: 2973
    • ScriptBasic Open Source Project
Re: winim
« Reply #3 on: January 08, 2020, 06:23:10 AM »
I have been playing with XML parsers and have come to the conclusion that ScriptBasic SPLITA and LIKE blows away anything I've tried. QuickBooks may just have a new scripting option. QBScript 😎
« Last Edit: January 08, 2020, 08:38:51 AM by John »