Dword c что это

от admin

Windows Programming/Handles and Data Types

One of the first things that is going to strike many first-time programmers of the Win32 API is that there are tons and tons of old data types to deal with. Sometimes, just keeping all the correct data types in order can be more difficult than writing a nice program. This page will talk a little bit about some of the data types that a programmer will come in contact with.

Contents

Hungarian Notation [ edit | edit source ]

First, let’s make a quick note about the naming convention used for some data types, and some variables. The Win32 API uses the so-called «Hungarian Notation» for naming variables. Hungarian Notation requires that a variable be prefixed with an abbreviation of its data type, so that when you are reading the code, you know exactly what type of variable it is. The reason this practice is done in the Win32 API is because there are many different data types, making it difficult to keep them all straight. Also, there are a number of different data types that are essentially defined the same way, and therefore some compilers will not pick up on errors when they are used incorrectly. As we discuss each data type, we will also note the common prefixes for that data type.

Putting the letter «P» in front of a data type, or «p» in front of a variable usually indicates that the variable is a pointer. The letters «LP» or the prefix «lp» stands for «Long Pointer», which is exactly the same as a regular pointer on 32 bit machines. LP data objects are simply legacy objects that were carried over from Windows 3.1 or earlier, when pointers and long pointers needed to be differentiated. On modern 32-bit systems, these prefixes can be used interchangeably.

LPVOID [ edit | edit source ]

LPVOID data types are defined as being a «pointer to a void object». This may seem strange to some people, but the ANSI-C standard allows for generic pointers to be defined as «void*» types. This means that LPVOID pointers can be used to point to any type of object, without creating a compiler error. However, the burden is on the programmer to keep track of what type of object is being pointed to.

Also, some Win32 API functions may have arguments labeled as «LPVOID lpReserved». These reserved data members should never be used in your program, because they either depend on functionality that hasn’t yet been implemented by Microsoft, or else they are only used in certain applications. If you see a function with an «LPVOID lpReserved» argument, you must always pass a NULL value for that parameter — some functions will fail if you do not do so.

LPVOID objects frequently do not have prefixes, although it is relatively common to prefix an LPVOID variable with the letter «p», as it is a pointer.

DWORD, WORD, BYTE [ edit | edit source ]

These data types are defined to be a specific length, regardless of the target platform. There is a certain amount of additional complexity in the header files to achieve this, but the result is code that is very well standardized, and very portable to different hardware platforms and different compilers.

DWORDs (Double WORDs), the most commonly occurring of these data types, are defined always to be unsigned 32-bit quantities. On any machine, be it 16, 32, or 64 bits, a DWORD is always 32 bits long. Because of this strict definition, DWORDS are very common and popular on 32-bit machines, but are less common on 16-bit and 64-bit machines.

WORDs (Single WORDs) are defined strictly as unsigned 16-bit values, regardless of what machine you are programming on. BYTEs are defined strictly as being unsigned 8-bit values. QWORDs (Quad WORDs), although rare, are defined as being unsigned 64-bit quantities. Putting a «P» in front of any of these identifiers indicates that the variable is a pointer. putting two «P»s in front indicates it’s a pointer to a pointer. These variables may be unprefixed, or they may use any of the prefixes common with DWORDs. Because of the differences in compilers, the definition of these data types may be different, but typically these definitions are used:

Notice that these definitions are not the same in all compilers. It is a known issue that the GNU GCC compiler uses the long and short specifiers differently from the Microsoft C Compiler. For this reason, the windows header files typically will use conditional declarations for these data types, depending on the compiler being used. In this way, code can be more portable.

As usual, we can define pointers to these types as:

DWORD variables are typically prefixed with «dw». Likewise, we have the following prefixes:

Data Type Prefix
BYTE «b»
WORD «w»
DWORD «dw»
QWORD «qw»

LONG, INT, SHORT, CHAR [ edit | edit source ]

These types are not defined to a specific length. It is left to the host machine to determine exactly how many bits each of these types has.

Types LONG notation LONG variables are typically prefixed with an «l» (lower-case L). UINT notation UINT variables are typically prefixed with an «i» or a «ui» to indicate that it is an integer, and that it is unsigned. CHAR, UCHAR notation These variables are usually prefixed with a «c» or a «uc» respectively.

If the size of the variable doesn’t matter, you can use some of these integer types. However, if you want to exactly specify the size of a variable, so that it has a certain number of bits, use the BYTE, WORD, DWORD, or QWORD identifiers, because their lengths are platform-independent and never change.

STR, LPSTR [ edit | edit source ]

STR data types are string data types, with storage already allocated. This data type is less common than the LPSTR. STR data types are used when the string is supposed to be treated as an immediate array, and not as a simple character pointer. The variable name prefix for a STR data type is «sz» because it’s a zero-terminated string (ends with a null character).

Most programmers will not define a variable as a STR, opting instead to define it as a character array, because defining it as an array allows the size of the array to be set explicitly. Also, creating a large string on the stack can cause greatly undesirable stack-overflow problems.

LPSTR stands for «Long Pointer to a STR», and is essentially defined as such:

LPSTR can be used exactly like other string objects, except that LPSTR is explicitly defined as being ASCII, not unicode, and this definition will hold on all platforms. LPSTR variables will usually be prefixed with the letters «lpsz» to denote a «Long Pointer to a String that is Zero-terminated». The «sz» part of the prefix is important, because some strings in the Windows world (especially when talking about the DDK) are not zero-terminated. LPSTR data types, and variables prefixed with the «lpsz» prefix can all be used seamlessly with the standard library <string.h> functions.

TCHAR [ edit | edit source ]

TCHAR data types, as will be explained in the section on Unicode, are generic character data types. TCHAR can hold either standard 1-byte ASCII characters, or wide 2-byte Unicode characters. Because this data type is defined by a macro and is not set in stone, only character data should be used with this type. TCHAR is defined in a manner similar to the following (although it may be different for different compilers):

TSTR, LPTSTR [ edit | edit source ]

Strings of TCHARs are typically referred to as TSTR data types. More commonly, they are defined as LPTSTR types as such:

These strings can be either UNICODE or ASCII, depending on the status of the UNICODE macro. LPTSTR data types are long pointers to generic strings, and may contain either ASCII strings or Unicode strings, depending on the environment being used. LPTSTR data types are also prefixed with the letters «lpsz».

HANDLE [ edit | edit source ]

HANDLE data types are some of the most important data objects in Win32 programming, and also some of the hardest for new programmers to understand. Inside the kernel, Windows maintains a table of all the different objects that the kernel is responsible for. Windows, buttons, icons, mouse pointers, menus, and so on, all get an entry in the table, and each entry is assigned a unique address known as a HANDLE. If you want to pick a particular entry out of that table, you need to give Windows the HANDLE value, and Windows will return the corresponding table entry.

HANDLEs are defined as void pointers (void*). They are used as unique identifiers to each Windows object in our program such as a button, a window an icon, etc. Specifically their definition follows: typedef PVOID HANDLE; and typedef void *PVOID; In other words HANDLE = void*.

HANDLEs are generally prefixed with an «h». Handles are unsigned integers that Windows uses internally to keep track of objects in memory. Windows moves objects like memory blocks in memory to make room, if the object is moved in memory, the handles table is updated.

Below are a few special handles that are worth discussing:

HWND [ edit | edit source ]

HWND data types are «Handles to a Window», and are used to keep track of the various objects that appear on the screen. To communicate with a particular window, you need to have a copy of the window’s handle. HWND variables are usually prefixed with the letters «hwnd», just so the programmer knows they are important.

Canonically, main windows are defined as:

Child windows are defined as:

and Dialog Box handles are defined as:

Although you are free to name these variables whatever you want in your own program, readability and compatibility suffer when an idiosyncratic naming scheme is chosen — or worse, no scheme at all.

HINSTANCE [ edit | edit source ]

HINSTANCE variables are handles to a program instance. Each program gets a single instance variable, and this is important so that the kernel can communicate with the program. If you want to create a new window, for instance, you need to pass your program’s HINSTANCE variable to the kernel, so that the kernel knows what program instance the new window belongs to. If you want to communicate with another program, it is frequently very useful to have a copy of that program’s instance handle. HINSTANCE variables are usually prefixed with an «h», and furthermore, since there is frequently only one HINSTANCE variable in a program, it is canonical to declare that variable as such:

It is usually a benefit to make this HINSTANCE variable a global value, so that all your functions can access it when needed.

HMENU [ edit | edit source ]

If your program has a drop-down menu available (as most visual Windows programs do), that menu will have an HMENU handle associated with it. To display the menu, or to alter its contents, you need to have access to this HMENU handle. HMENU handles are frequently prefixed with simply an «h».

WPARAM, LPARAM [ edit | edit source ]

In the earlier days of Microsoft Windows, parameters were passed to a window in one of two formats: WORD-length (16-bit) parameters, and LONG-length (32-bit) parameters. These parameter types were defined as being WPARAM (16-bit) and LPARAM (32-bit). However, in modern 32-bit systems, WPARAM and LPARAM are both 32 bits long. The names however have not changed, for legacy reasons.

Читать:
Кто определяет количество всех участников олимпийских игр

WPARAM and LPARAM variables are generic function parameters, and are frequently type-cast to other data types including pointers and DWORDs.

Типы данных в Win32 API

В WINAPI определено множество типов данных, так же, как и в C/С++ ( int , char , float и т.д.). Учить их определения не обязательно. Достаточно помнить, что они существуют, а когда они появятся или потребуются где-нибудь в программе, посмотреть их определения. В дальнейшем мы будем использовать их все. Условно их можно разделить на несколько видов: основные, дескрипторные, строковые и вспомогательные.

Основные типы

С основными типами данных трудностей возникнуть не должно. Если всё же возникнут, то нужно сюда.

BOOL – этот тип данных аналогичен bool . Он также имеет два значения – 0 или 1. Только при использовании WINAPI принято использовать вместо 0 спецификатор NULL . О нём ниже.

BYTE – байт, ну или восьмибитное беззнаковое целое число. Аналог – unsigned char .

DWORD — 32-битное беззнаковое целое. Аналоги: unsigned long int , UINT .

INT – 32-битное целое. Аналог – long int .

LONG – 32-битное целое – аналог всё также long int .

NULL – нулевой указатель. Вот его объявление:

UINT – 32-битное беззнаковое целое. Аналоги: unsigned long int , DWORD .

Дескрипторные типы данных

Про дескрипторные типы немного рассказывалось на вводном уроке в WINAPI. Дескриптор, как говорилось ранее, — это идентификатор какого-либо объекта. Для разных типов объектов существуют разные дескрипторы. Дескриптор объекта можно описать так:

Есть также дескрипторы кисти, курсора мыши, шрифта и т.д. С их помощью мы можем при инициализации или в процессе работы приложения поменять какие-нибудь настройки, чего, например, мы не могли сделать в консольном приложении. Используются они в описательных функциях, управляющих типа: CreateProcess(), ShowWindow() и т.д. или как возвращаемое значение некоторых функций :

В этой функции мы получили дескриптор считывания потоков std_in и std_out. И можем, например, его использовать в каком-нибудь условии.

Не будем вдаваться в физику создания дескрипторов. Разве что, при необходимости или для большего понимания процессов.

HANDLE – дескриптор объекта.

HBITMAP – дескриптор растрового изображения. От фразы handle bitmap.

HBRUSH – дескриптор кисти. От фразы handle brush.

HCURSOR – дескриптор курсора. От фразы handle cursor.

HDC – дескриптор контекста устройства. От фразы handle device context.

HFONT – дескриптор шрифта. От фразы handle font.

HICONS – дескриптор криптограммы. От фразы handle icons.

HINSTANCE – дескриптор экземпляра приложения. От фразы handle instance.

HMENU – дескриптор меню. От фразы handle menu.

HPEN – дескриптор пера. От фразы handle pen.

HWND – дескриптор окна. От фразы handle window.

Строковые типы данных

Для начала начнём, с того, какие кодировки существуют в Windows ОС.

Есть два вида кодировок символов: ANSI и UNICODE. Однобайтные символы относятся к ANSI, двухбайтные — к кодировке UNICODE. Мы можем с лёгкостью подключить UNICODE кодировку в свойствах проекта. И тогда в коде создать переменную типа char можно будет так:

Если же мы хотим использовать кодировку ANSI, то мы традиционно напишем:

В WINAPI, в зависимости от того, подключён юникод или нет, используются два вида строк UNICODE-ные или TCHAR-ные. Ниже описаны строковые типы данных.

LPCSTR – указатель на константную строку, заканчивающуюся нуль-терминатором. От фразы long pointer constant string.

LPCTSTR – указатель на константную строку, без UNICODE. От фразы long pointer constant TCHAR string. Это надстройка функции LPCSTR.

LPCWSTR – указатель на константную UNICODE строку. От фразы фразы long pointer constant wide character string. Это надстройка функции LPCSTR.

LPSTR – указатель на строку, заканчивающуюся нуль-терминатором. От фразы long pointer string.

LPTSTR – указатель на строку, без UNICODE. От фразы long pointer TCHAR string. Это надстройка функции LPSTR.

LPWSTR – указатель на UNICODE строку. От фразы long pointer wide character string. Это надстройка функции LPSTR.

TCHAR – символьный тип — аналог char и wchar_t.

Вспомогательные типы

Вспомогательные типы данных используются в некоторых функциях. В частности, параметры, описанные ниже, используются при работе с функцией обратного вызова оконной процедуры такого вида:

Работа с данной функцией будет в следующих разделах.

LPARAM – тип для описания lParam (long parameter). Используются вместе с wparam в некоторых функциях.

LRESULT – значение, возвращаемое оконной процедурой имеет тип long .

WPARAM – тип для описания wParam (word parameter). Используются вместе с lParam в некоторых функциях.

На этом типы данных не закончены. В дальнейшем мы обязательно будем обращаться к данной статье.

Why in C++ do we use DWORD rather than unsigned int? [duplicate]

I’m not afraid to admit that I’m somewhat of a C++ newbie, so this might seem like a silly question but.

I see DWORD used all over the place in code examples. When I look up what a DWORD truly means, its apparently just an unsigned int (0 to 4,294,967,295). So my question then is, why do we have DWORD? What does it give us that the integral type ‘unsigned int’ does not? Does it have something to do with portability and machine differences?

4 Answers 4

DWORD is not a C++ type, it’s defined in <windows.h> .

The reason is that DWORD has a specific range and format Windows functions rely on, so if you require that specific range use that type. (Or as they say «When in Rome, do as the Romans do.») For you, that happens to correspond to unsigned int , but that might not always be the case. To be safe, use DWORD when a DWORD is expected, regardless of what it may actually be.

For example, if they ever changed the range or format of unsigned int they could use a different type to underly DWORD to keep the same requirements, and all code using DWORD would be none-the-wiser. (Likewise, they could decide DWORD needs to be unsigned long long , change it, and all code using DWORD would be none-the-wiser.)

Also note unsigned int does not necessary have the range 0 to 4,294,967,295. See here.

When MS-DOS and Windows 3.1 operated in 16-bit mode, an Intel 8086 word was 16 bits, a Microsoft WORD was 16 bits, a Microsoft DWORD was 32 bits, and a typical compiler’s unsigned int was 16 bits.

When Windows NT operated in 32-bit mode, an Intel 80386 word was 32 bits, a Microsoft WORD was 16 bits, a Microsoft DWORD was 32 bits, and a typical compiler’s unsigned int was 32 bits. The names WORD and DWORD were no longer self-descriptive but they preserved the functionality of Microsoft programs.

When Windows operates in 64-bit mode, an Intel word is 64 bits, a Microsoft WORD is 16 bits, a Microsoft DWORD is 32 bits, and a typical compiler’s unsigned int is 32 bits. The names WORD and DWORD are no longer self-descriptive, AND an unsigned int no longer conforms to the principle of least surprises, but they preserve the functionality of lots of programs.

Dword c что это

This forum has migrated to Microsoft Q&A. Visit Microsoft Q&A to post new questions.

Visual studio home link

  • ProfileText
  • Sign in

Answered by:

Question

hi i just needed some quick info , recently i just needed to terminate a thread from outside. So i googled a little bit and
I came up with TerminateThread function. I also found out the drawbacks of using TerminateThread. Since terminatethread was doing the
job perfectly i decided to further look up at its syntax and i came up with the following results

BOOL TerminateThread(HANDLE thread, DWORD status);

and I use it in the following manner
if( TerminateThread(Thread,0)) <. >where thread is my handle to the thread

anyways i wanted to know what is DWORD status for ?? and why am i keeping it 0 in above call??
and what is LPVOID .

I would really appreciate the info.thank you A candle loses nothing by lighting another candle.

Answers

Quote>what is DWORD status for ? and what is LPVOID ?

TIP: Open the Win32 SDK help. In the index enter DWORD and press enter.
The Help page with the title: "Windows Data Types" should open.

Can also be found online here:

  • Marked as answer by Silver_Gates Monday, September 21, 2009 11:26 PM

All replies

In MSDN, for the TerminateThread the second parameter it is not called status. It is called "exitcode", and it tips, under some circumstances (if coded that way), the "main" thread about an abnormal termination of a "worker" thread. Thus can be done using GetExitCodeThread also documented on MSDN. This function it used to retreive the "exitcode" ("status" if you wish) specified or by the TerminateThread or by the ExitThread.

LPVOID means (if I am not wrong) Long Pointer void, same as void* .

It is not recommended that you terminate a thread using TerminateThread (depending on the OS platform, the stack of the terminated thread might not be released); you are using the function in the right way.

PS: DWORD means Double WORD. WORD is 16bit unsigned integer, so DWORD is 16bit x 2 = 32bit unsigned integer.

just visited the link and ended up with

A candle loses nothing by lighting another candle.

A big issue with the C and C++ languages is that the data size of the primitive data types are not standardized. That’s a big problem because code always cares a lot about the size of, say, an int. This forces any API to declare typedefs that nail down the actual data type. DWORD is such a typedef for a 32-bit unsigned integer. It is unsigned int today, it used to be unsigned long when Windows was a 16-bit operating system. LPVOID is void*. There are many others, you must have seen LPCWSTR before.

Another fun problem with this is that every library must declare its own typedefs to avoid colliding with the typedefs of another library. That’s most visible with strings. In every-day C/C++ coding, you’ll have to know char*, wchar_t*, TCHAR*, LPSTR, LPCSTR, LPTSTR, LPCTSTR, LPWSTR, LPCWSTR, BSTR, _bstr_t, LPOLESTR, LPCOLESTR, UNICODE_STRING, CStringT, CString, std::string, std::wstring, System::String. That’s just from Microsoft.

More fun when 64-bit operating systems became available. Even though in 64-bit code a 64-bit integer is the native type, Microsoft decided to leave an int 32 bits and, somewhat controversially in my book, even a long at 32-bits. A native int requires __int64. Admittedly, it makes 32-bit Windows code easy to port. More typedefs were needed in the SDK headers though to be able to handle the "pointer as an integer" construct. Visible artifacts of that are DWORD_PTR, UINT_PTR, INT_PTR, LONG_PTR, SIZE_T, ULONG_PTR and API changes like GetWindowLongPtr(). More of that in the C/C++ and MIDL compiler with __int3264, __w64.

Well, back on topic, passing 0 to TerminateThread makes little sense. 0 means "it’s normal", pass something "not normal". But much worse, TerminateThread is one of those API functions you should never ever use. The SDK docs are explicit:

TerminateThread is a dangerous function that should only be used in the most extreme cases.

It gives you a list of all the things that can go wrong. What is missing is what I thought was a problem for a long time, maybe they fixed it. It leaks the memory allocated for the thread stack.

Похожие статьи