comp.lang.ada
 help / color / mirror / Atom feed
* Re: Win32 dialogs/resource grief (longish)
  2000-03-02  0:00 ` Jerry van Dijk
@ 2000-03-01  0:00   ` David Botton
  2000-03-02  0:00     ` John English
  0 siblings, 1 reply; 6+ messages in thread
From: David Botton @ 2000-03-01  0:00 UTC (permalink / raw)


Actually that was not his problem. Your version of the code would also have
seen the same problem if you threw in the second dialog box.

BTW rcl also does not compile the resource to coff correctly in that case
either (mutliple dialogs). Windres or M$ cvtres are the only options here.

David Botton

Jerry van Dijk wrote in message <38bdb710_1@news2.prserv.net>...
>Basically, the problem is that passing around data within the
>Win32 environment takes more care. Explaining it all would take
>more then a posting, but hopefully the code below will point in
>the right direction.









^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Win32 dialogs/resource grief (longish)
  2000-03-01  0:00 Win32 dialogs/resource grief (longish) John English
@ 2000-03-01  0:00 ` David Botton
  2000-03-02  0:00 ` Jerry van Dijk
  1 sibling, 0 replies; 6+ messages in thread
From: David Botton @ 2000-03-01  0:00 UTC (permalink / raw)


Your problem is the tools, not the code.

res2coff is botching up the job.

You must place both dlgs in a single resource script. Create your res and
then run MS's cvtres on it. If you want to go all the way GNU use windres
and include a line like this at the start of your resource

#include "E:\gnat\mingw32\include\windows32\defines.h"

That will suck in the defines for your resources.

So again:

1. All resources in one .rc file
2. use windres, or any rc program and MS cvtres

I have a copy of windres at

http://www.adapower.com/com/windres.zip

David Botton

John English wrote in message <38BC8428.901597BD@brighton.ac.uk>...
>I have a problem with an apparent bug to do with using resources
>with the Win32 binding -- long post, sorry, but it's stripped as
>far down as I can manage. I'm using Gnat 3.12 here. Any advice
>*much* appreciated -- I'm running out of walls to bang my head
>against :-(


>
>  brcc32 combodlg.rc
>  res2coff -i combodlg.res -o combodlg.o
>  brcc32 yesnodlg.rc
>  res2coff -i yesnodlg.res -o yesnodlg.o
>  gnatmake test_dialogs.adb









^ permalink raw reply	[flat|nested] 6+ messages in thread

* Win32 dialogs/resource grief (longish)
@ 2000-03-01  0:00 John English
  2000-03-01  0:00 ` David Botton
  2000-03-02  0:00 ` Jerry van Dijk
  0 siblings, 2 replies; 6+ messages in thread
From: John English @ 2000-03-01  0:00 UTC (permalink / raw)


I have a problem with an apparent bug to do with using resources
with the Win32 binding -- long post, sorry, but it's stripped as
far down as I can manage. I'm using Gnat 3.12 here. Any advice
*much* appreciated -- I'm running out of walls to bang my head
against :-(

I have two simple dialogs: one with a label, combo box and OK/Cancel
buttons, another with a label and Yes/No/Cancel buttons. They work
fine individually, but not together. I've tried putting the dialogs
in the same resource file and in separate files; it makes no difference.

The test program (test_dialogs.adb) looks like this:

  with Test_YesNo;            -- 1
  with Test_Combo;            -- 2
  procedure Test_Dialogs is
  begin
    Test_YesNo.Do_Dialog;     -- 3
    Test_Combo.Do_Dialog;     -- 4
  end Test_Dialogs;

The Yes/No dialog fails unless both lines 2 and 4 are commented out.
Commenting out line 4 only has no effect. I've also seen the combo
box dialog fail unless lines 1 and 3 are commented out. The fact that
the "with" clause needs to be commented out strikes me as significant,
but I don't know exactly what it signifies -- any ideas, anyone? Using
"GetLastError" and "FormatError" to find out what the error in the call
to DialogBox is, I get one of two messages: "The specified procedure
could not be found", or more puzzlingly, "The operation completed
successfully" (this when DialogBox returns -1 to signify failure!).

The resources were compiled using the Borland resource compiler "brcc32"
from the BC++ 5.02 distribution and converted to COFF files using
res2coff
from Gnat 3.12. Here's the compilation sequence:

  brcc32 combodlg.rc
  res2coff -i combodlg.res -o combodlg.o
  brcc32 yesnodlg.rc
  res2coff -i yesnodlg.res -o yesnodlg.o
  gnatmake test_dialogs.adb

The packages specs referenced on lines 1 and 2 of Test_Dialogs are as
follows:

  package Test_Combo is
    procedure Do_Dialog;
  end Test_Combo;

  package Test_YesNo is
    procedure Do_Dialog;
  end Test_YesNo;

The bodies are as follows:

  with Win32, Win32.WinMain, Win32.WinDef, Win32.WinUser,
       Ada.Text_IO, System, Interfaces.C, Test_Common;
  use  Test_Common;
  package body Test_Combo is
    pragma Linker_Options("combodlg.o");
    use type Win32.Char_Array;

    COMBOBOX  : constant := 1020;  -- combobox control ID from
combodlg.rc

    function ComboDlg_Handler (hwnd   : Win32.WinDef.HWND;
                               msg    : Win32.UINT;
                               wParam : Win32.WPARAM;
                               lParam : Win32.LPARAM) return Win32.BOOL;
    pragma Convention (Stdcall, ComboDlg_Handler);

    Result  : Integer;
    Options : constant array (1..3) of Win32.Char_Array(1..6) := 
              ("Yes  " & Win32.NUL,
               "No   " & Win32.NUL,
               "Maybe" & Win32.NUL);

    function ComboDlg_Handler (hwnd   : Win32.WinDef.HWND;
                               msg    : Win32.UINT;
                               wParam : Win32.WPARAM;
                               lParam : Win32.LPARAM) return Win32.BOOL
is
      Dummy : Win32.LRESULT;
    begin
      case msg is
        when Win32.WinUser.WM_INITDIALOG =>
          for I in Options'Range loop
            Dummy := Win32.WinUser.SendMessage 
                        (Win32.WinUser.GetDlgItem(hwnd,COMBOBOX),
                         Win32.WinUser.CB_ADDSTRING, 0,
                         CP(Options(I)));
          end loop;
          return Win32.TRUE;
        when Win32.WinUser.WM_COMMAND =>
          case wParam is
            when Win32.WinUser.IDOK =>
              Result := Integer(Win32.WinUser.SendMessage 
                                 
(Win32.WinUser.GetDlgItem(hwnd,COMBOBOX),
                                   Win32.WinUser.CB_GETCURSEL, 0, 0));
              return Win32.WinUser.EndDialog (hwnd, Win32.TRUE);
            when Win32.WinUser.IDCANCEL =>
              return Win32.WinUser.EndDialog (hwnd, Win32.FALSE);
            when others =>
              return Win32.FALSE;
          end case;
        when others =>
          return Win32.FALSE;
      end case;                         
    end ComboDlg_Handler;

    procedure Do_Dialog is
      I : Interfaces.C.Int;
    begin
      Ada.Text_IO.Put_Line ("--- Combo box dialog test ---");
      I := Win32.WinUser.DialogBox
                  (Win32.WinMain.Get_hInstance,
                   CP("ComboDlg"),
                   System.Null_Address,
                   ComboDlg_Handler'Access);
      Ada.Text_IO.Put_Line ("Return value:" &
Integer'Image(Integer(I)));
      Ada.Text_IO.Put_Line ("Result:" & Integer'Image(Result));
    end Do_Dialog;
  end Test_Combo;

  with Win32, Win32.WinDef, Win32.WinMain, Win32.WinUser, Interfaces.C,
       Ada.Text_IO, Ada.Unchecked_Conversion, System, Test_Common;
  use  Test_Common;
  package body Test_YesNo is
    pragma Linker_Options("yesnodlg.o");
    use type Interfaces.C.Unsigned;

    function YesNoDlg_Handler (hwnd   : Win32.WinDef.HWND;
                               msg    : Win32.UINT;
                               wParam : Win32.WPARAM;
                               lParam : Win32.LPARAM) return Win32.BOOL;
    pragma Convention (Stdcall, YesNoDlg_Handler);

    Result : Boolean;

    function YesNoDlg_Handler (hwnd   : Win32.WinDef.HWND;
                               msg    : Win32.UINT;
                               wParam : Win32.WPARAM;
                               lParam : Win32.LPARAM) return Win32.BOOL
is
    begin
      case msg is
        when Win32.WinUser.WM_INITDIALOG =>
          return Win32.TRUE;
        when Win32.WinUser.WM_COMMAND =>
          case wParam is
            when Win32.WinUser.IDYES | Win32.WinUser.IDNO =>
              Result := (wParam = Win32.WinUser.IDYES);
              return Win32.WinUser.EndDialog (hwnd, Win32.TRUE);
            when Win32.WinUser.IDCANCEL =>
              return Win32.WinUser.EndDialog (hwnd, Win32.FALSE);
            when others =>
              return Win32.FALSE;
          end case;
        when others =>
          return Win32.FALSE;
      end case;                         
    end YesNoDlg_Handler;

    procedure Do_Dialog is
      I : Interfaces.C.Int;
    begin
      Ada.Text_IO.Put_Line ("--- Yes/no dialog test ---");
      I := Win32.WinUser.DialogBox
                  (Win32.WinMain.Get_hInstance,
                   CP("YesNoDlg"),
                   System.Null_Address,
                   YesNoDlg_Handler'Access);
      Ada.Text_IO.Put_Line ("Return value:" &
Integer'Image(Integer(I)));
      Ada.Text_IO.Put_Line ("Result: " & Boolean'Image(Result));
    end Do_Dialog;
  end Test_YesNo;

The package Test_Common contains a couple of type conversion routines:

  with Win32, Interfaces.C;
  package Test_Common is
    function CP(C_Str : Win32.CHAR_Array) return Interfaces.C.LONG;
    function CP(C_Str : Win32.CHAR_Array) return Win32.LPCSTR;
  end Test_Common;

  with Win32, System, Interfaces.C, Ada.Unchecked_Conversion;
  package body Test_Common is
    use type Interfaces.C.Unsigned_Long;
  
    function CP(C_Str : Win32.CHAR_Array) return Interfaces.C.LONG is
      function UC is new Ada.Unchecked_Conversion
                             (System.Address,Interfaces.C.LONG);
    begin
      return UC(C_Str(C_Str'First)'Address);
    end CP;

    function CP(C_Str : Win32.CHAR_Array) return Win32.LPCSTR is
      function UC is new Ada.Unchecked_Conversion
                             (System.Address,Win32.LPCSTR);
    begin
      return UC(C_Str(C_Str'First)'Address);
    end CP;
  end Test_Common;

The resources are defined thusly:

  /*--- yesnodlg.rc ---*/
  YesNoDlg DIALOG 6, 15, 166, 39
  STYLE DS_3DLOOK | DS_CENTER | 0x200L | WS_POPUP | WS_VISIBLE |
WS_CAPTION
  CAPTION "Yes/no dialog"
  FONT 9, "Arial"
  {
   LTEXT "Press a button:", 1004, 8, 4, 131, 12
   DEFPUSHBUTTON "Yes", IDYES, 12, 20, 42, 13
   PUSHBUTTON "No", IDNO, 64, 20, 42, 13
   PUSHBUTTON "Cancel", IDCANCEL, 116, 20, 42, 13
  }

  /*--- combodlg.rc ---*/
  ComboDlg DIALOG 6, 15, 147, 56
  STYLE DS_3DLOOK | DS_CENTER | 0x200L | WS_POPUP | WS_VISIBLE |
WS_CAPTION
  CAPTION "Input required"
  FONT 9, "Arial"
  {
   LTEXT "Choose a value:", 1002, 8, 4, 131, 12
   COMBOBOX 1020, 7, 18, 132, 78, CBS_DROPDOWNLIST | WS_CHILD |
WS_VISIBLE | WS_TABSTOP
   DEFPUSHBUTTON "OK", IDOK, 23, 36, 42, 13
   PUSHBUTTON "Cancel", IDCANCEL, 83, 36, 42, 13
  }

Please help! This is driving me mad!

-----------------------------------------------------------------
 John English              | mailto:je@brighton.ac.uk
 Senior Lecturer           | http://www.it.bton.ac.uk/staff/je
 Dept. of Computing        | ** NON-PROFIT CD FOR CS STUDENTS **
 University of Brighton    |    -- see http://burks.bton.ac.uk
-----------------------------------------------------------------




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Win32 dialogs/resource grief (longish)
  2000-03-01  0:00 Win32 dialogs/resource grief (longish) John English
  2000-03-01  0:00 ` David Botton
@ 2000-03-02  0:00 ` Jerry van Dijk
  2000-03-01  0:00   ` David Botton
  1 sibling, 1 reply; 6+ messages in thread
From: Jerry van Dijk @ 2000-03-02  0:00 UTC (permalink / raw)


> I have two simple dialogs: one with a label, combo box and OK/Cancel
> buttons, another with a label and Yes/No/Cancel buttons. They work
> fine individually, but not together. I've tried putting the dialogs
> in the same resource file and in separate files; it makes no difference.

Basically, the problem is that passing around data within the
Win32 environment takes more care. Explaining it all would take
more then a posting, but hopefully the code below will point in
the right direction.

Compile with:
rcl -i yesnodlg.rc yesnodlg.o
gnatmake test_dialogs

-- test_dialogs.adb ----------------
with YesNo_Dialog;

procedure Test_Dialogs is
begin
   YesNo_Dialog.Do_Dialog;
end Test_Dialogs;

-- yesno_dialog.ads ----------------
package YesNo_Dialog is

   procedure Do_Dialog;
   --  execute dialog

end YesNo_Dialog;

-- yesno_dialog.adb ----------------
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Unchecked_Conversion;

with Win32;          use Win32;
with Win32.Windef;   use Win32.Windef;
with Win32.Winuser;  use Win32.Winuser;
with Win32.Windowsx; use Win32.Windowsx;

with Resources; use Resources;

package body YesNo_Dialog is

   -------------------------
   -- Generic subprograms --
   -------------------------

   type Integer_Access is access all Integer;
   function To_LPARAM is new Ada.Unchecked_Conversion (Integer_Access,
LPARAM);
   function To_Access is new Ada.Unchecked_Conversion (LPARAM,
Integer_Access);
   --  for moving an integer pointer around

   -------------------------
   -- Private subprograms --
   -------------------------

   function YesNo_DlgProc (Dlg_Handle  : HWND;
                           Dlg_Message : UINT;
                           Dlg_wParam  : WPARAM;
                           Dlg_lParam  : LPARAM)
                           return BOOL;
   pragma Convention (StdCall, YesNo_DlgProc);
   --  Dialog procedure

   function On_Init (Dlg_Handle : HWND;
                     Dlg_Focus  : HWND;
                     Dlg_lParam : LPARAM)
                     return Win32.BOOL;
   --  handle dialog initialization

   procedure On_Command (Dlg_Handle        : HWND;
                         Control_Id        : INT;
                         Control_Handle    : HWND;
                         Notification_Code : UINT);
   --  handle dialog commands

   --------------------
   -- Execute Dialog --
   --------------------

   procedure Do_Dialog is
      Result : INT;
      Button : aliased Integer;
   begin
      Put_Line ("--- Yes/no dialog test ---");
      Result := DialogBoxParam (GetWindowInstance (Desktop_Handle),
                                LPCSTR (MAKEINTRESOURCE (YesNo_Dlg)),
                                Desktop_Handle,
                                YesNo_DlgProc'Access,
                                To_LPARAM (Button'Unchecked_Access));
      Put_Line ("Dialog result code:" & Result'Img);
      Put ("Button pressed: ");
      case Button is
         when IDYES    => Put_Line ("Yes");
         when IDNO     => Put_Line ("No");
         when IDCANCEL => Put_Line ("Cancel");
         when others   => Put_Line ("Unknown");
      end case;
   end Do_Dialog;

   ----------------------
   -- Dialog procedure --
   ----------------------

   function YesNo_DlgProc (Dlg_Handle  : HWND;
                           Dlg_Message : UINT;
                           Dlg_wParam  : WPARAM;
                           Dlg_lParam  : LPARAM)
                           return BOOL
   is
   begin
      case Dlg_Message is
         when WM_INITDIALOG =>
            return BOOL (HANDLE_WM_INITDIALOG (Dlg_Handle,
                                               Dlg_wParam,
                                               Dlg_lParam,
                                               On_Init'Access));
         when WM_COMMAND =>
            return BOOL (HANDLE_WM_COMMAND (Dlg_Handle,
                                            Dlg_wParam,
                                            Dlg_lParam,
                                            On_Command'Access));
         when others =>
            return Win32.FALSE;
      end case;
   end YesNo_DlgProc;

   ----------------------------------
   -- Handle dialog initialization --
   ----------------------------------

   function On_Init (Dlg_Handle : HWND;
                     Dlg_Focus  : HWND;
                     Dlg_lParam : LPARAM)
                     return Win32.BOOL
   is
      Result : LONG;
   begin
      Result := SetWindowLong (Dlg_Handle, GWL_USERDATA, Dlg_lParam);
      return Win32.TRUE;
   end On_Init;

   ----------------------------
   -- Handle dialog commands --
   ----------------------------

   procedure On_Command (Dlg_Handle        : HWND;
                         Control_Id        : INT;
                         Control_Handle    : HWND;
                         Notification_Code : UINT)
   is
      Result : BOOL;
      Button : Integer_Access;
   begin
      Button := To_Access (GetWindowLong (Dlg_Handle, GWL_USERDATA));
      case Control_Id is
         when IDNO =>
            Button.all := IDNO;
            Result := EndDialog (Dlg_Handle, Win32.TRUE);
         when IDYES =>
            Button.all := IDYES;
            Result := EndDialog (Dlg_Handle, Win32.TRUE);
         when IDCANCEL =>
            Button.all := IDCANCEL;
            Result := EndDialog (Dlg_Handle, Win32.TRUE);
         when others =>
            null;
      end case;
   end On_Command;

end YesNo_Dialog;

-- resources.ads ----------------
with System; use System;

with Win32.Windef; use Win32.Windef;

package Resources is

   pragma Linker_Options ("yesnodlg.o");
   --  link the dialog resources

   Desktop_Handle : constant HWND := Null_Address;
   --  Handle to the desktop 'window'

   YesNo_Dlg : constant := 1000;
   --  dialog resource identifiers

end Resources;

/* -- yesnodlg.rc --------------- */
#include <Windows32/defines.h>
1000 DIALOG 6, 15, 166, 39
STYLE DS_3DLOOK | DS_CENTER | 0x200L | WS_POPUP | WS_VISIBLE | WS_CAPTION
CAPTION "Yes/no dialog"
FONT 9, "Arial"
BEGIN
   LTEXT "Press a button:", 1004, 8, 4, 131, 12
   DEFPUSHBUTTON "Yes", IDYES, 12, 20, 42, 13
   PUSHBUTTON "No", IDNO, 64, 20, 42, 13
   PUSHBUTTON "Cancel", IDCANCEL, 116, 20, 42, 13
END







^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Win32 dialogs/resource grief (longish)
  2000-03-02  0:00     ` John English
@ 2000-03-02  0:00       ` David Botton
  0 siblings, 0 replies; 6+ messages in thread
From: David Botton @ 2000-03-02  0:00 UTC (permalink / raw)



John English wrote in message <38BE69BC.18BC5895@bton.ac.uk>...
>As it happens, Windres seems to give me the same result.

I sent you the working versions of your code that use Windres. Make sure
that you are including both resources in a single .rc script. If not, even
Windres can not help you.

>Gnat complains that at least 160 bits (20 bytes) are required for
>Dialog, so I have to drop Menu from the rep clause (but thankfully
>it still works fine) -- any idea why 20 bytes are required when the
>size has explicitly been set to 18 bytes?


I'll try and take a look when I get a chance, but you should probably send a
note to report@gnat.com since ACT frequently looks in to these matters and
often makes fixes to Win32Ada.

David Botton









^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Win32 dialogs/resource grief (longish)
  2000-03-01  0:00   ` David Botton
@ 2000-03-02  0:00     ` John English
  2000-03-02  0:00       ` David Botton
  0 siblings, 1 reply; 6+ messages in thread
From: John English @ 2000-03-02  0:00 UTC (permalink / raw)


David Botton wrote:
> 
> Actually that was not his problem. Your version of the code would also have
> seen the same problem if you threw in the second dialog box.
> 
> BTW rcl also does not compile the resource to coff correctly in that case
> either (mutliple dialogs). Windres or M$ cvtres are the only options here.
> 
> David Botton
> 
> Jerry van Dijk wrote in message <38bdb710_1@news2.prserv.net>...
> >Basically, the problem is that passing around data within the
> >Win32 environment takes more care. Explaining it all would take
> >more then a posting, but hopefully the code below will point in
> >the right direction.

As it happens, Windres seems to give me the same result. I've haven't
got cvtres so I haven't tried it, but I manually converted my .rc
file into about 500 lines of type declarations for DLGTEMPLATE
structures, with delicate rep clauses and alignment clauses (yuk!),
and everything now works perfectly. But if I can find a copy of
cvtres I'll give it a try -- I don't want to have to do any more
manual conversions if I can avoid it! A pox on tools that don't
work...

Incidentally, a funny with the DLGTEMPLATE. In Win32.WinUser, the
size clause for DLGTEMPLATE says "for 'Size use 18*8" -- but when
I set up my DLGTEMPLATE structure like so:

  type MyDlg is
    record
      Dialog : DLGTEMPLATE;  -- 18 bytes
      Menu   : WORD := 0;    -- 2 bytes
      Class  : WORD := 0;    -- 2 bytes
      ...
    end record;

  for MyDlg use
    record
      Dialog at 0  range 0..18*8-1;
      Menu   at 18 range 0..15;
      Class  at 20 range 0..15;
    end record;

Gnat complains that at least 160 bits (20 bytes) are required for
Dialog, so I have to drop Menu from the rep clause (but thankfully
it still works fine) -- any idea why 20 bytes are required when the
size has explicitly been set to 18 bytes?

Anyway, many thanks for your help, David.

-----------------------------------------------------------------
 John English              | mailto:je@brighton.ac.uk
 Senior Lecturer           | http://www.it.bton.ac.uk/staff/je
 Dept. of Computing        | ** NON-PROFIT CD FOR CS STUDENTS **
 University of Brighton    |    -- see http://burks.bton.ac.uk
-----------------------------------------------------------------




^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2000-03-02  0:00 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-03-01  0:00 Win32 dialogs/resource grief (longish) John English
2000-03-01  0:00 ` David Botton
2000-03-02  0:00 ` Jerry van Dijk
2000-03-01  0:00   ` David Botton
2000-03-02  0:00     ` John English
2000-03-02  0:00       ` David Botton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox