This is to avoid what is called a false positive, i.e. when the user receives an alert about a danger while there was actually no danger at all.
Do you remember this rich era when, while you were browsing the Internet, you where facing a dozen of times per day an alert bow stating something like "Alert ! The web page you are viewing contains some secured elements and some unsecured elements ! Are you sure you want to proceed !". The result of this was just that people were trained to ignore their browser's alert message and blindly click on the OK button, which was fully counter-productive from the security point-of-view.
Now this is the same with your
SetWindowsHookEx API call. An anti-virus has no way to determine the intent of a software, it can only rely on a subset of facts. So, maybe the use of this API call enters as a part of an heuristic taking into account several other parameters helping the anti-virus to determine when a software has got a suspicious behavior, but the sole presence of this API call is not sufficient since it is also used by many authorized applications (same thing if you write a simple Batch file deleting all your documents: your anti-virus will not prevent you from running it).
These are the very reason why, while anti-virus provide a good level of protection against well-known malware, it can never be a bullet-proof protection and the first and better line of defense remains the user who should be properly educated in recognizing and refrain from opening suspicious files.