Error 49, “Bad DLL calling convention”, means a Declare call passed arguments in a way the DLL function does not accept. The count, the types, or the passing mechanism (ByVal versus ByRef) disagrees with the real function, so the stack is left unbalanced and VBA raises error 49, if it is lucky; if it is unlucky, the application crashes instead. It is always a defect in the Declare statement or the call, never in the data.
long is VBA Long in 32-bit and still Long (not LongLong) in 64-bit for most API parameters; pointers and handles are LongPtr.' Wrong on 64-bit: handle declared As Long truncates the pointer
' Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
' (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
ByVal so VBA hands over a converted pointer to text. Declaring a string parameter ByRef (the default) is a classic error 49, or crash, cause.If the signature matches the documentation exactly and error 49 persists, the documentation may describe a different version of the library than the one installed. Confirm the DLL version on the machine, and check whether the function uses a calling convention (such as cdecl in some third-party libraries) that VBA Declare cannot call at all; those need a wrapper, not a better Declare.
Does error 49 mean the DLL is broken? No. The DLL is usually fine; the VBA declaration of how to call it is wrong. The error is raised because the arguments placed on the stack did not match what the function removed from it.
Why do old Declare statements fail on 64-bit Office? Because pointer-sized values changed. Handles and pointers declared As Long are truncated, and without PtrSafe the declaration does not even compile cleanly; at run time the mismatch surfaces as error 49 or a crash.