Correctly Passing Window Handle to DLL

Windows specific forum
LiK137
Enthusiast
Enthusiast
Posts: 279
Joined: Wed Jun 23, 2010 5:13 pm

Correctly Passing Window Handle to DLL

Post by LiK137 »

Hi,
According to code below, marked with red a dll function accepts integer windows handle as argument and returns pointer.

Code: Select all

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
using System.Reflection;

namespace libRollDllTest
{
   public partial class MainForm : Form
   {
      RollPanel roll_frame;
      bool f_mode_;
      public MainForm()
      {
         InitializeComponent();
         roll_frame = new RollPanel();
         roll_frame.Location = new System.Drawing.Point(0, 0);
         roll_frame.Name = "RollFrame place holder";
         roll_frame.Size = this.RollTab.Size;
         roll_frame.BackColor = System.Drawing.SystemColors.Desktop;
         this.RollTab.Controls.Add(roll_frame);
         roll_frame.Paint += Roll_Paint;
         roll_frame.Dock = DockStyle.Fill;
         CreateButton.Click += CreateScanner;
         f_mode_ = true;
      }

      private void CreateScanner(object sender, System.EventArgs e)
      {
         roll_frame.CreateScanner();
      }

      private void StartButton_Click(object sender, EventArgs e)
      {
         plainPrintsBox.Enabled = false;
         roll_frame.Start();
      }

   }

   public class RollPanel : Panel
   {
      IntPtr h_scanner;
      IntPtr h_roll_frame;
      bool live_view;
      bool touch_mode;
#if !DEBUG
      const string lib_name = "librolldll.dll";
#else
      const string lib_name = "librolldll.dll";
#endif

      #region Messages from roll frame
      const int WM_USER       = 0x400;
      const int WM_INITED     = WM_USER + 100;
      const int WM_INI_FAILED = WM_USER + 101;
      const int WM_PREVIEW    = WM_USER + 102;
      const int WM_CLEAR_PREVIEW = WM_USER + 103;
      const int WM_IMAGE         = WM_USER + 104;
      const int WM_SCAN_COMPLETED   = WM_USER + 105;
      const int WM_REMOVE_FINGER    = WM_USER + 106;
      const int WM_STATE         = WM_USER + 107;
      const int WM_BUTTON        = WM_USER + 108;

      #endregion

      #region Functions of Roll_API.dll

      [DllImport(lib_name)]
      extern private static IntPtr Create(IntPtr form_h);
      [DllImport(lib_name)]
      extern private static void Init(IntPtr dev_h, int device);
      #endregion

      public RollPanel()
      {
         h_scanner = IntPtr.Zero;
         h_roll_frame = IntPtr.Zero;
         live_view = false;
         touch_mode = false;
         this.DoubleBuffered = true;
      }

      protected override void WndProc(ref Message m)
      {
         if (m.Msg == WM_STATE)
         {
            int state = (int)m.WParam;
            string msg = "state changed to " + state.ToString();
            MessageBox.Show(msg, "Message",
            MessageBoxButtons.OK, MessageBoxIcon.Information);
         }
         else if (m.Msg == WM_BUTTON)
         {
            int button_mask = (int)m.WParam;
            string msg = "button pressed " + button_mask.ToString();
            MessageBox.Show(msg, "Message",
            MessageBoxButtons.OK, MessageBoxIcon.Information);
         }
         else
         {
            base.WndProc(ref m);
         }

      }

      public bool CreateScanner()
      {
         if (h_scanner == IntPtr.Zero)
         {
                                    h_scanner = Create(this.Handle);
                                    Init(h_scanner, 15);
         }
                                    return h_scanner != IntPtr.Zero;
      }
      
      public void Start()
      {
         Start(h_scanner);
      }

   }
}

Very simple code in my conversion does not return Pointer to h_scanner

Code: Select all


;{ Evts
#WM_INITED = #WM_USER+100
#WM_INI_FAILED = #WM_USER+101
#WM_PREVIEW = #WM_USER+102
#WM_CLEAR_PREVIEW = #WM_USER+103
#WM_IMAGE = #WM_USER+104
#WM_SCAN_COMPLETED = #WM_USER+105
#WM_REMOVE_FINGER = #WM_USER+106
#WM_STATE = #WM_USER+107
#WM_BUTTON = #WM_USER+108
;}
;{ ProtoLibRollDll
Global librolldllLIB.l = OpenLibrary(#PB_Any, "../librolldll.dll")

If librolldllLIB > 0 
  PrototypeC.l LR_Create(HWND):Global LR_Create.LR_Create = GetFunction(librolldllLIB. "LR_Create") ; H_DEVICE
  PrototypeC.l LR_Init(*H_DEVICE,dev_typ.l):Global LR_Init.LR_Init = GetFunction(librolldllLIB, "Init") ; LRErr
  PrototypeC.l LR_Start(*H_DEVICE):Global LR_Start.LR_Start = GetFunction(librolldllLIB, "Start") ; Int
EndIf
;}

  Debug "dlLoadOk: librolldllLIB: "+librolldllLIB

  Global *h_Dev, *h_roll_frame, HWND.l, live_view.b = #False, touch_mode.b = #False
  Define *pLCD, *lut
  
Procedure WndProc(hWnd, uMsg, wParam, lParam)
  result = #PB_ProcessPureBasicEvents
  If uMsg = #WM_STATE
    state.i = WParam
    msg.s = "state changed to " + PeekS(state)
    Debug msg
  ElseIf uMsg = #WM_BUTTON
    button_mask.i = WParam
    msg.s = "button pressed " + PeekS(button_mask)
    Debug msg  
  Else
    ProcedureReturn result  
  EndIf  
EndProcedure    

Procedure LSCreate()
               *h_Dev= LR_Create(HWND);
                LR_Init(*h_Dev, 15);
                ProcedureReturn *h_Dev
EndProcedure
Procedure LStart()
  If *h_Dev
    LR_Start(*h_Dev);
  EndIf
EndProcedure

  HWND.l = OpenWindow(#PB_Any, 0, 0, 600, 600, "MyWin")
  Debug HWND
  SetWindowCallback(@WndProc(), HWND)
  
  LSCreate()
;   LStart()
Repeat
    Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
;}
;}  
I tried passing handle to function but everytime got read error at address 0
Last edited by LiK137 on Thu Sep 20, 2018 11:21 am, edited 1 time in total.
PeDe
Enthusiast
Enthusiast
Posts: 119
Joined: Sun Nov 26, 2017 3:13 pm
Location: Vienna
Contact:

Re: Correctly Passing Window Handle to DLL

Post by PeDe »

Look at the PureBasic function WindowID(#Window). With it you get the real handle.
And HWND.l (long) is only for 32-bit.

Peter
LiK137
Enthusiast
Enthusiast
Posts: 279
Joined: Wed Jun 23, 2010 5:13 pm

Re: Correctly Passing Window Handle to DLL

Post by LiK137 »

ThanQ PeDe,
I have tried both way in 32bit PB:

WindowID(0,...) - in case of OpenWindow(0,....)
And
HWND.l - in case of HWND.l = WindowID(#pb_any,...)
WindowID and HWND give same correct handle.

I think the problem is nearly:

declaration

Code: Select all

      IntPtr h_scanner; 
and then making it zero

Code: Select all

      h_scanner = IntPtr.Zero; 

After that calling

Code: Select all

      h_scanner = Create(this.Handle); 

Runs and returns normal handle.

In the source there is no structure used.
How can be translated to PB the following lines

Code: Select all

      IntPtr h_scanner; 
               h_scanner = IntPtr.Zero; 
PeDe
Enthusiast
Enthusiast
Posts: 119
Joined: Sun Nov 26, 2017 3:13 pm
Location: Vienna
Contact:

Re: Correctly Passing Window Handle to DLL

Post by PeDe »

I'm sorry, I don't understand you.
I see:

Code: Select all

PrototypeC.l LR_Create(HWND)
Global HWND.l
...
Procedure LSCreate()
   *h_Dev= LR_Create(HWND);
   LR_Init(*h_Dev, 15);
   ProcedureReturn *h_Dev
EndProcedure
...
HWND.l = OpenWindow(#PB_Any, 0, 0, 600, 600, "MyWin")
LSCreate()
...
With WindowID() it could be like this:

Code: Select all

PrototypeC.l LR_Create(HWND)
Global HWND.l
...
Procedure LSCreate()
   *h_Dev= LR_Create(HWND);
   LR_Init(*h_Dev, 15);
   ProcedureReturn *h_Dev
EndProcedure
...
Number.l = OpenWindow(#PB_Any, 0, 0, 600, 600, "MyWin")
HWND = WindowID(Number)
LSCreate()
...
Peter
LiK137
Enthusiast
Enthusiast
Posts: 279
Joined: Wed Jun 23, 2010 5:13 pm

Re: Correctly Passing Window Handle to DLL

Post by LiK137 »

Hi Peter,
Thank You very much for reply.
You are absolutely right regarding WindowID(), that gets real handle.
But as I told, I tried both variants, #WindowNumber and WindowID(WindowNumber) and no luck

Could You please tell me (I searched forum regarding declaring and setting to zero the handle as in C# but did not succeed finding way) how to handle the following:

Code: Select all

  IntPtr h_scanner; 
  h_scanner = IntPtr.Zero;
Thank You in advance
PeDe
Enthusiast
Enthusiast
Posts: 119
Joined: Sun Nov 26, 2017 3:13 pm
Location: Vienna
Contact:

Re: Correctly Passing Window Handle to DLL

Post by PeDe »

I guess you can use #NULL for this when I read the documentation here.
https://docs.microsoft.com/en-us/dotnet ... work-4.7.2

Code: Select all

h_scanner = #NULL
Peter
LiK137
Enthusiast
Enthusiast
Posts: 279
Joined: Wed Jun 23, 2010 5:13 pm

Re: Correctly Passing Window Handle to DLL

Post by LiK137 »

yes, absolutely correct, #Null but not 0
Thank You Peter
Post Reply