STRICT Compliance

{}from MSDN & MFC source code

STRICT
Compliance

Some source code that compiles successfully might produce error messages when you enable STRICT type checking. The following sections describe the minimal requirements for making your code compile when STRICT is enabled. Additional steps are recommended, especially to produce portable code.

General Requirements

The principal requirement is that you must declare correct handle types and function pointers instead of relying on more general types. You cannot use one handle type where another is expected. This also means that you may have to change function declarations and use more type casts.

For best results, the generic HANDLE type should be used only when necessary.

Declaring Functions Within Your Application

Make sure all application functions are declared. Placing all function declarations in an include file is recommended because you can easily scan your declarations and look for parameter and return types that should be changed.

If you use the /Zg compiler option to create header files for your functions, remember that you'll get different results depending on whether you have enabled STRICT type checking. With STRICT disabled, all handle types generate the same base type. With STRICT enabled, they generate different base types. To avoid conflict, you need to re-create the header file each time you enable or disable STRICT, or edit the header file to use the types HWND, HDC, HANDLE, and so on, instead of the base types.

Any function declarations that you copied from Windows.h into your source code may have changed, and your local declaration may be out of date. Remove your local declaration.

Types that Require Casts

Some functions have generic return types or parameters. For example, the SendMessage function returns data that may be any number of types, depending on the context. When you see any of these functions in your source code, make sure that you use the correct type cast and that it is as specific as possible. The following list is an example of these functions.

LocalLock
GlobalLock
GetWindowLong
SetWindowLong
SendMessage
DefWindowProc
SendDlgItemMessage

When you call SendMessage, DefWindowProc, or SendDlgItemMessage, you should first cast the result to type UINT. You need to take similar steps for any function that returns an LRESULT or LONG value, where the result contains a handle. This is necessary for writing portable code because the size of a handle varies, depending on the version of Windows. The (UINT) cast ensures proper conversion. The following code shows an example in which SendMessage returns a handle to a brush:

HBRUSH hbr;

 

hbr = (HBRUSH)(UINT)SendMessage(hwnd, WM_CTLCOLOR, ..., ...);

The CreateWindow and CreateWindowEx hmenu parameter is sometimes used to pass an integer control identifier (ID). In this case, you must cast the ID to an HMENU type:

HWND hwnd;

int id;

 

hwnd = CreateWindow("Button", "Ok", BS_PUSHBUTTON,

        x, y, cx, cy, hwndParent,

        (HMENU)id,      // Cast required here

        hinst,

        NULL);

Additional Considerations

To get the most benefit from STRICT type checking, there are additional guidelines you should follow. Your code will be more portable in future versions of Windows if you make the following changes.

The types WPARAM, LPARAM, LRESULT, and LPVOID are polymorphic data types. They hold different kinds of data at different times, even when STRICT type checking is enabled. To get the benefit of type checking, you should cast values of these types as soon as possible. (Note that message crackers automatically recast wParam and lParam for you in a portable way.)

Take special care to distinguish HMODULE and HINSTANCE types. Even with STRICT enabled, they are defined as the same base type. Most kernel module management functions use HINSTANCE types, but there are a few functions that return or accept only HMODULE types.

#ifdef STRICT

typedef void *HANDLE;

#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name

#else

typedef PVOID HANDLE;

#define DECLARE_HANDLE(name) typedef HANDLE name

#endif

typedef HANDLE *PHANDLE;

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值