1

How do I prevent Access Violation error with this code:

function UsbWndProc(hWnd: hWnd; Msg: UINT; wParam, lParam: Longint)
  : Longint; stdcall;
begin
  try
    if fPrevWndProc <> nil then
      Result := CallWindowProc(fPrevWndProc, hWnd, Msg, wParam, lParam);
    if (Msg = WM_DEVICECHANGE) and (mUSBDetector <> nil) then
      mUSBDetector.DeviceChanged(Msg, wParam, lParam);
  except
    ;
  end;
end;

Here's the log from MadExcept:

   callstack crc     : $0d3f54dd, $7c7e133d, $d174bae3
    exception number  : 1
    exception class   : EAccessViolation
    exception message : Access violation at address 0059D5CF in module 'XXX.exe'. Read of address 00000010.
main thread ($8b0):
0059d5cf +00f XXX.exe    Vcl.Forms               TCustomForm.IsFormSizeStored
0059d5b5 +005 XXX.exe    Vcl.Forms               TCustomForm.IsClientSizeStored
0059fd4b +59b XXX.exe    Vcl.Forms               TCustomForm.CreateParams
0050073e +02e XXX.exe    Vcl.Controls            TWinControl.CreateWnd
0059bf99 +005 XXX.exe    Vcl.Forms               TScrollingWinControl.CreateWnd
0059fdc6 +00a XXX.exe    Vcl.Forms               TCustomForm.CreateWnd
00500c82 +016 XXX.exe    Vcl.Controls            TWinControl.CreateHandle
00504a04 +01c XXX.exe    Vcl.Controls            TWinControl.HandleNeeded
00504a11 +005 XXX.exe    Vcl.Controls            TWinControl.GetHandle
005a5ae9 +02d XXX.exe    Vcl.Forms               GetTopMostWindows
765f376c +011 USER32.dll                           EnumWindows
005a5bad +02d XXX.exe    Vcl.Forms               TApplication.DoNormalizeTopMosts
005a5c82 +002 XXX.exe    Vcl.Forms               TApplication.NormalizeTopMosts
005a64c2 +326 XXX.exe    Vcl.Forms               TApplication.WndProc
0048668c +014 XXX.exe    System.Classes          StdWndProc
765f1b52 +016 USER32.dll                           CallWindowProcW
008446b8 +034 XXX.exe    U_Usb     86  +3 UsbWndProc
77c96fcb +02b ntdll.dll                            KiUserCallbackDispatcher
004fefae +0ae XXX.exe    Vcl.Controls            TWinControl.Destroy

008446ab 86   push    edi
008446ac      push    esi
008446ad      push    ebx
008446ae      mov     eax, [ebp+8]
008446b1      push    eax
008446b2      mov     eax, [$902f6c]
008446b7      push    eax
008446b8    > call    -$431be9 ($412ad4)     ; Winapi.Windows.CallWindowProc
008446b8
008446bd      mov     [ebp-4], eax

Line 86 is Result := CallWindowProc(fPrevWndProc, hWnd, Msg, wParam, lParam);

I have added try-except but the Access Violation error sometimes occurs in my program especially when I close the program.

Thanks.

Charles Sungkono
  • 145
  • 2
  • 10
  • 2
    You need to show how you are replacing the window procedure. – Sertac Akyuz May 27 '12 at 15:36
  • The source code taken from http://stackoverflow.com/questions/1930008/how-to-find-the-unique-serial-number-of-a-flash-device. procedure TMainForm.Usb(Sender: TObject; Drive: string; Attached: Boolean); begin if Attached then bla; end; – Charles Sungkono May 27 '12 at 15:40
  • I couldn't duplicate the AV here with that code. – Sertac Akyuz May 27 '12 at 16:16
  • Sometimes it happens. MadExcept catches the AV and show that CallWindowProc produce the error. – Charles Sungkono May 27 '12 at 16:38
  • Uncomment `//SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(@fPrevWndProc)); `? – Charles Sungkono May 27 '12 at 18:55
  • So the code become `Result := CallWindowProc(@fPrevWndProc, hWnd, Msg, wParam, lParam); `? What do we call this problem? I mean, why if I add `@` then the error won't happen? – Charles Sungkono May 28 '12 at 02:57
  • Never mind, it's not related with the AV in your question. – Sertac Akyuz May 28 '12 at 08:57
  • @CharlesSungkono This `@` symbol is essential when working with pointers in Delphi, as well as the `^` symbol. Read here: http://delphi.about.com/od/objectpascalide/a/pointers.htm – Jerry Dodge May 29 '12 at 03:58
  • Yes, @Jerry, but it's also essential to know what `@` makes you point at. In this case, it makes you point at a function pointer. `CallWindowProc` doesn't want a pointer to a function pointer. It wants just a function pointer. Sertac has removed the erroneous comment. If you find yourself using `@` with function pointers, you're *probably* doing something wrong. – Rob Kennedy May 30 '12 at 17:29
  • @Rob - I tried to figure out if OP has uncommented the erroneous statement in the linked source (`//SetWindowLong(Application.Handle,GWL_WNDPROC,LongInt(@fPrevWndProc));` notice the incorrect @) and getting errors due to that. But I was unable to communicate at all, whatever I said it went haywire. In the end I gave up and deleted my comments. – Sertac Akyuz May 31 '12 at 17:03

0 Answers0