Jonas Maebe wrote:


On 04 Jan 2006, at 21:51, Hans Mårtensson wrote:
The type of pBoxtemplate is ^word.

Is it not true that
 (dword(pBoxtemplate) and 1)=1
evaluates to TRUE, if and only if pBoxtemplate is NOT aligned to a word boundary (16 bit boundary)?

And then, assuming pBoxtemplate is aligned to word boundary, is it not true, that
 if (dword(pBoxtemplate) and 2)=2
evaluates to TRUE, if pBoxtemplate is NOT aligned to a dword boundary (32 bit boudary), causing the statement
 if (dword(pBoxtemplate) and 2)=2 then inc(pBoxtemplate);
to make the pBoxtemplate align to a dword boundary (by eventually adding 2 to pBoxtemplate (because sizeof(word)=2)??


Yes, but this is independent of how the compiler handles alignment of data.


OK, then I really don't understand where the problem is.

It seems difficult to me to supply a bug report, because it is still so uncertain where the problem lies. But I attach the source code to my test program, in case you can do anything with it.

When I compile this source code with FPC 1.0.10, it produces a program that makes a window with one menu item. When you click on it, a dialogue box pops up.

But when I compile the same source code with FPC 2.0.2, I still get a program that makes the window. But the dialogue box does not show, when you click the menu item.

Hans Mårtensson

Program test;
// Program for testing dialogue boxes

{$APPTYPE GUI}

Uses windows;

Const
  AppName = 'Lydexperiment';

var 
  AMessage: Msg; hWindow: HWnd;
  pbox2: pointer; box2var1, box2var2: longint;

  Boxtemplate: DlgTemplate;
  Boxtemplatesize: word;
  pBoxAllokate: ^word; //Start of allocated memory
  pBoxtemplate: ^word; //Start of Boxtemplate
  pBoxItem: ^word;     //Start of free space after added items

{$Rangechecks off}
//**************************************************************
Procedure newboxtemplate(title: string; width, height, boxsize: word);
var i:integer;
begin boxtemplatesize:=boxsize; pBoxItem:=nil;
  getmem(pBoxAllokate,boxsize); pBoxtemplate:=pBoxAllokate;
  if (dword(pBoxtemplate) and 1)=1 then pBoxtemplate:=nil;
  if (dword(pBoxtemplate) and 2)=2 then inc(pBoxtemplate);
  if pBoxtemplate=nil then exit;
  Boxtemplate.style:=DS_CENTER or WS_POPUP or WS_CAPTION or WS_SYSMENU or 
DS_MODALFRAME;
  Boxtemplate.dwextendedstyle:=0;
  Boxtemplate.x:=0; Boxtemplate.y:=0; Boxtemplate.cx:=width; 
Boxtemplate.cy:=height;
  Boxtemplate.cdit:=0; pBoxItem:=pointer(pBoxtemplate) + sizeof(Boxtemplate);
  pBoxItem^:=0; inc(pBoxItem); pBoxItem^:=0; inc(pBoxItem); // menu and class
  for i:=1 to length(title) do begin pBoxItem^:=ord(title[i]); inc(pBoxItem) 
end;
  pBoxItem^:=0; inc(pBoxItem) end; // terminating 0 in titel

Procedure newboxtemplate(title: string; width, height: word);
begin newboxtemplate(title, width, height, 2000) end;

//**************************************************************
Procedure appendboxitem(id: word; style: DWORD; class: word; title: string; 
x,y,width,height: WORD);
var i: word; Bi: Dlgitemtemplate;
begin if pBoxItem=nil then exit; if (dword(pBoxItem) and 2)=2 then 
inc(pBoxItem);
  Bi.style:=style or WS_VISIBLE or WS_CHILD;
  if class<>$82 then Bi.style:=BI.style or WS_TABSTOP;
  Bi.dwextendedstyle:=0;
  Bi.x:=x; Bi.y:=y; Bi.cx:=width; Bi.cy:=height;  Bi.id:=id;
  move(Bi,pBoxItem^,sizeof(Bi)); inc(pBoxItem,sizeof(bi) div 2);
  pBoxItem^:=$FFFF; inc(pBoxItem);  pBoxItem^:=class; inc(pBoxItem); 
//standard-class presumed
  for i:=1 to length(title) do begin pBoxItem^:=ord(title[i]); inc(pBoxItem) 
end;
  pBoxItem^:=0; inc(pBoxItem); // terminating 0 in titel
  pBoxItem^:=0; inc(pBoxItem); // creation data is not used
  inc(Boxtemplate.cdit); move(Boxtemplate,pBoxtemplate^,sizeof(Boxtemplate));
  end;

Function getboxtemplate: pointer;
var nbox: DWORD; pBoxny: ^word;
begin if pBoxItem=nil then begin
    getboxtemplate:=nil; MessageBox (0,'WinCreate failed','Error',MB_OK); exit 
end
  else getboxtemplate:=pBoxtemplate;
  nbox := pointer(pBoxItem) - pointer(pBoxAllokate); getmem(pBoxny,nbox+2);
  if pBoxny=nil then exit;
  if (dword(pBoxny) and 1)=1 then pBoxny:=nil;
  if (dword(pBoxny) and 2)=2 then begin inc(pBoxny); dec(nbox,2) end;
  move(pBoxtemplate^,pBoxny^,nbox); freemem(pBoxAllokate,Boxtemplatesize);
  pBoxtemplate:=pBoxny; getboxtemplate:=pBoxny; pBoxItem:=nil end;

//**************************************************************
//End of dialogue box data structure making procedures

//Start of specific dialogue box definition
//******************************************************************************
Function Box2Proc(Box: hWnd; Message: UINT; WPrm : longint; LPrm: longint): 
Longint; stdcall;
begin Box2Proc:=1; if LPrm=0 then ;
  case Message of
    WM_INITDIALOG: begin box2var1:=8000; box2var2:=2;
      case box2var1 of
        8000: Checkradiobutton(Box,2,7,2);
        11025: Checkradiobutton(Box,2,7,3);
        16000: Checkradiobutton(Box,2,7,4);
        22050: Checkradiobutton(Box,2,7,5);
        48000: Checkradiobutton(Box,2,7,6);
        44100: Checkradiobutton(Box,2,7,7);
        end;
      if box2var2>1 then CheckDlgButton(Box,8,BST_CHECKED)
      else CheckDlgButton(Box,8,BST_UNCHECKED);
      setfocus(longint(Box)); Box2Proc:=0 end;
    WM_COMMAND: case LOWORD(WPrm) of
      2: begin Checkradiobutton(Box,2,7,2); box2var1:=8000 end;
      3: begin Checkradiobutton(Box,2,7,3); box2var1:=11025 end;
      4: begin Checkradiobutton(Box,2,7,4); box2var1:=16000 end;
      5: begin Checkradiobutton(Box,2,7,5); box2var1:=22050 end;
      6: begin Checkradiobutton(Box,2,7,6); box2var1:=48000 end;
      7: begin Checkradiobutton(Box,2,7,7); box2var1:=44100 end;
      8: if box2var2>1 then begin box2var2:=1; 
CheckDlgButton(Box,8,BST_UNCHECKED) end
        else begin box2var2:=2; CheckDlgButton(Box,8,BST_CHECKED) end;
      9: begin enddialog(Box,1) end end;
    WM_CLOSE: enddialog(Box,0);
    else Box2Proc:=0 end end;

Procedure showbox(window: hWnd);
begin if DialogBoxIndirect(system.MainInstance,pBox2, Window, @Box2Proc)=0 then 
exit end;

//******************************************************************************

Procedure setboxtemplates;
begin
  newboxtemplate('Lydkvalitet',87,90);
  appendboxitem(1,SS_SIMPLE,$82,'Samplerate (s. pr. sek.)',5,5,80,12);
  appendboxitem(2,BS_AUTORADIOBUTTON,$80,'8000',5,20,40,12);
  appendboxitem(3,BS_AUTORADIOBUTTON,$80,'11025',50,20,40,12);
  appendboxitem(4,BS_AUTORADIOBUTTON,$80,'16000',5,35,40,12);
  appendboxitem(5,BS_AUTORADIOBUTTON,$80,'22050',50,35,40,12);
  appendboxitem(6,BS_AUTORADIOBUTTON,$80,'48000',5,50,40,12);
  appendboxitem(7,BS_AUTORADIOBUTTON,$80,'44100',50,50,40,12);
  appendboxitem(8,BS_CHECKBOX,$80,'Stereo',6,68,40,12);
  appendboxitem(9,BS_DEFPUSHBUTTON,$80,'OK',50,70,30,12);
  pBox2:=getboxtemplate;  
  end;

//*****************************************************************************
//End of specific dialogue box definition

//The rest of the program is for making a window
//*****************************************************************************

Function WindowProc(Window: hWnd; AMessage: UINT; WPrm: WParam; LPrm: LParam): 
LResult; stdcall; export;
Var nrmenu: longint; //ps: paintstruct; dc: hdc; r: rect;
begin WindowProc := 0;
  Case AMessage of
//    wm_Paint: begin
//      dc:=BeginPaint(Window,@ps);
//      EndPaint(Window,ps);
//      Exit;
//      end;
    wm_Close: ; //Lad DefWindowProc take care of close
    wm_Destroy: begin PostQuitMessage(0); exit end;
    wm_char: ;
    wm_Command: begin
      NrMenu := WPrm and $FFFF;
      Case NrMenu Of
        100: showbox(window);
        End; End; End;
  WindowProc := DefWindowProc(Window,AMessage,WPrm,LPrm); End;

//**************************************************************
Function WinRegister: Boolean;
var  WindowClass: WndClass;
Begin With WindowClass Do Begin
    Style := cs_hRedraw Or cs_vRedraw;
    lpfnWndProc := WndProc(@WindowProc);
    cbClsExtra := 0;
    cbWndExtra := 0;
    hInstance := system.MainInstance;
    hIcon := LoadIcon(0,idi_Application);
    hCursor := LoadCursor(0,idc_Arrow);
    hbrBackground := GetStockObject(LTGRAY_BRUSH);
    lpszMenuName := '';
    lpszClassName := AppName;
    End;
  WinRegister := RegisterClass(WindowClass)<>0;
  If not WinRegister then begin MessageBox(0,'Register failed',Nil, mb_Ok); 
exit end;
  end;

//**************************************************************
Function WinCreate: hWnd;
Var hWindow: hWnd;
    Menu: hMenu;
Begin
  hWindow := CreateWindow(AppName,AppName,ws_OverlappedWindow,
  
cw_UseDefault,cw_UseDefault,cw_UseDefault,cw_UseDefault,0,0,system.MainInstance,Nil);
  If hWindow<>0 then begin
    Menu := CreateMenu;
    AppendMenu(Menu,MF_STRING,100,'&Show dialogbox for test');
    SetMenu(hWindow,Menu);
    ShowWindow(hWindow,CmdShow);
    ShowWindow(hWindow,SW_SHOW);
    UpdateWindow(hWindow);
    end;
  Wincreate := hWindow
  end;


//*************** Main program **********************************
Begin
  If not WinRegister then exit;
  hWindow := WinCreate;
  If longint(hWindow)=0 then begin MessageBox (0,'WinCreate failed',Nil,MB_OK); 
exit end;
  setboxtemplates;
  While GetMessage(@AMessage,0,0,0) do
  begin TranslateMessage(AMessage); DispatchMessage(AMessage) end;
  Halt(AMessage.wParam) End.
_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply via email to