Windows message Daquan

xiaoxiao2021-04-05  242

Compilation analysis of advanced language programs

In advanced languages, such as C and Pascal, we no longer operate directly to hardware resources, but to solve problems, this is mainly reflected in data abstraction and program structure. For example, we use variable name to access data, and no longer care about where this data is in memory. In this way, the use of hardware resources is completely handed over to the compiler. However, some basic rules still exist, and most compilers have followed some specification, which makes we have a good day when they read the disassembly code. Here mainly talks about some and advanced languages ​​in the assembly code.

1. Ordinary variable. Usually declared variables are stored in memory. The compiler linked the variable name and a memory address (hereby, the so-called "determined address" is a temporary address calculated on the compiler in the compiler. Loading to memory in the compiler. A series of adjustments such as relocation is performed during the execution, generate a real-time memory address, but this does not affect the logic of the program, so don't care too much about these details, just know that all the function names and variable names correspond to one. The address of the memory is OK), so the variable name is characterized by a valid address in the assembly code, which is the operand in square brackets. For example, declare in a C file:

INT my_age;

This integer variable has a specific memory location. Statement MY_AGE = 32; may be manifested in the disassembly code:

MOV Word PTR [007E85DA], 20

Therefore, the valid address in square brackets corresponds to the variable name. As another example:

CHAR MY_NAME [11] = "Lianzi2000";

Such an explanation has also determined an address corresponding to my_name. Assume the address is 007E85DC, and [007E85DC] = 'L', [007e85dd] = 'i', ETC. accesses to MY_NAME are also the address of this address. data access.

The pointer variable itself also corresponds to an address because it is also a variable. Such as:

CHAR * YOUR_NAME;

At this time, it is also determined that the variable "Your_Name" corresponds to a memory address, assuming to 007E85F0. Statement Your_name = my_name; It is likely to be manifested:

MOV [007E85F0], 007E85DC; Your_Name's content is the address of my_name.

2. Register variable

Register variables are allowed in C and C . Register INT i; indicating that i is an integer variable stored by the register. Typically, the compiler places the register variable in ESI and EDI. The register is the structure inside the CPU, which is much more than the memory, so the frequent use variable can be placed in the register.

3. A number of groups

Regardless of the number of dimensional arrays, all elements are always stored in memory, so it is always one-dimensional in memory. For example, INT i_ARRAY [2] [3]; the memory determines an address from which 12 bytes starting from the address is used to store the elements of the array. So the variable name I_Array corresponds to the start address of the array, that is, the first element pointing to the array. The order of storage is generally i_Array [0] [0], [0] [1], [0] [2], [1] [0], [1] [1], [1] [2] is the rightmost The subscript is the fastest. When you need to access an element, the program will be converted from the multi-dimensional index value into one-dimensional index, such as accessing i_Array [1] [1], converting a one-dimensional index value in memory is 1 * 3 1 = 4. This Conversion may be determined when compiling, or may be determined when it is running. Anyway, if we load the address corresponding to i_Array into a universal register as the base address, the access to array elements is a problem that calculates a valid address:

i_Array [1] [1] = 0x16

LEA EBX, XXXXXXXXX; I_ARRAY corresponds to EBX

Mov EDX, 04; Access I_Array [1] [1], it has been determined when compiling

MOV Word PTR [EBX EDX * 2], 16;

Of course, depending on the compiler and program context, the specific implementation may be different, but this basic form is determined. From here, the proportional factor can be seen (it is also remembering the value of 1, 2, 4 or 8?), Because simple variables are always 1, 2, 4 or 8 words in the current system The length of the section, so the proportional factor has a great convenience for the surfaction table operation in memory.

4. Structure and object

The members of the structure and objects are also stored continuously in memory, but in order to align in the word boundary or double word boundary, some minimally adjust, so determine that the size of the object should be used in the SizeOf operator without adding the size of the member. Calculate. This structural variable and object's name also correspond to a memory address when we declare a structural variable or initialize an object. for example:

Struct tag_info_struct

{

Int agec;

Int sex;

Float height;

Float weight;

marry;

The variable marry corresponds to a memory address. At this address, there is enough bytes (SizeOf (Marry) to accommodate all members. Each member corresponds to an offset relative to this address. Here, it is assumed that all members in this structure are continuously stored, then the relative address of the AGE is 0, and SEX is 2, Height is 4, and weight is 8.

Marry.sex = 0;

LEA EBX, XXXXXXXXX; Marry Corresponding memory address

MOV Word PTR [EBX 2], 0

......

The subject is basically the same. Note that the member function is implemented in the code segment, and in the object is a pointer to the function.

5. Function call

When a function is defined, it is also determined that a memory address corresponds to the function name. Such as:

Long Comb (int M, INT N)

{

Long Temp;

.....

Return Temp;

}

In this way, the function COMB corresponds to a memory address. The call to its call is:

Call XXXXXXXX; COMB corresponds to the address. This function requires two integer parameters, pass the stack:

LRESULT = COMB (2, 3);

Push 3

Push 2

Call xxxxxxxx

Mov DWORD PTR [YYYYYYYYY], EAX; YYYYYYYY is the address of long integer variable LRESULT

Please pay attention to two points here. First, in the C language, the stack order of the parameters is opposite to the parameter order, that is, the next parameter first stack, so the PUSH 3. Second, in the 32-bit system we discussed, if the parameters are not specified Type, default is to press 32-bit double words. Therefore, two PUSH instructions are compressed into two double words, namely 8 bytes of data. Then execute the CALL instruction. The CALL directive returns the address, the 32-bit address of the next instruction (Mov DWORD PTR ....) and then jumps to XXXXXXXX to execute.

At the entrance to the COMB subroutine (xxxxxxxx), the status of the stack is like this:

03000000 (please recall the Small Endian format)

02000000

YYYYYYYYYY <- ESP points to the return address

As mentioned earlier, the standard start code of the subroutine is like this:

Push EBP; save the original EBPMOV EBP, ESP; establish a frame pointer

SUB ESP, XXX; reserved space for temporary variables

.....

After performing the PUSH EBP, the stack is as follows:

03000000

02000000

YYYYYYYYYYYYYY

Old EBP <---- ESP points to the original EBP

After performing MOV EBP, ESP, both EBP and ESP points to the original EBP. Then Sub ESP, XXX leaves space for temporary variables. Here, only one temporary variable Temp is a long integer, requiring 4 bytes, so xxx = 4. This creates the framework of this subroutine:

03000000

02000000

YYYYYYYYYYYYYY

Old EBP <---- Current EBP points here

Temp

Therefore, the subroutine can obtain the first parameter (m) with [EBP 8], and the second parameter (N) is obtained with [EBP C] to push it. The temporary variable is under EBP, as TEMP here is corresponding to [EBP-4].

The subroutine is executed to the end, to return the value of TEMP:

Mov Eax, [EBP-04]

Then perform the opposite operation to revoke the frame:

Mov ESP, EBP; At this time, ESP and EBP points to OLD EBP, and temporary variables have been revoked.

POP EBP; Undo Frame pointer to restore the original EBP.

This is the ESP pointing to the address. The following RETN instruction returns the main program:

Retn 4

This instruction is loaded from the stack pop-up returns to the EIP, returning to the main program to perform the instructions behind the CALL. At the same time, adjust the ESP (ESP = ESP 4 * 2), so that the parameters are revoked, so that the stack is restored to the status of the caller, this is the balance of the stack. The stack balance should always be maintained before and after calling the subroutine. As can be seen from here, the temporary variable TEMP has disappeared as the subroutine is returned, so it is illegal to try to return a pointer to temporary variables.

In order to better support advanced languages, Intel also provides instruction Enter and Leave to dynamize the establishment and revoking of the framework. ENTER accepts two operands, the first one indicated to the number of bytes reserved for the temporary variable, the second is the number of subroutine nested calls, generally 0. ENTER XXX, 0 corresponds to:

Push EBP

MOV EBP, ESP

SUB ESP, XXX

Leave is equivalent to:

MOV ESP, EBP

POP EBP

============================================================================================================================================================================================================= ===========

- Author: saulia March 15, 2005, Tuesday 15:05 Reply (0) | Trackbacks (0). Add CASINO.

Preparation knowledge of assembly language - to the first contact assembler (3)

As a language, "assembly language", corresponding to the compiler of advanced languages, we need a "assembler" to edit the assembly language original file into machine executable code. Advanced assemblers such as MASM, TASM, etc. provide a lot of features similar to advanced languages, such as structuring, abstraction, etc. As a compiler prepared in such an environment, a large part is a directory for the assembler, which has been classified with advanced languages. The current assembly environment is so advanced, even if all of the assembly language is written in WINDOWS, it is also possible, but this is not the strengths of the assembly language. The length of the assembly language is to write efficient and need to control the programs for the machine hardware. And I think the purpose of people here is mostly the purpose of learning compilation. In order to understand the disassembly code when cracking, few people really have to collect language compilation? (Khan ...) Ok, the words retired. Most assembly language books are programmed for assembly language. My post is the machine and disassembly, hoping to compete with each other. With the foundation of the previous two, the introduction of most instructions on the assembly language book should be able to understand, understand. Here is some common and complicated instructions here. I am talking about the hard command of the machine, not for any assembler.

Unconditional transfer instruction JMP:

This kind of jump instruction has three ways: short (Near) and far. Short refers to the target address to be jumped to the current address before and after the phase of 128 bytes. Recently, the target address of the jump and the current address are in one segment, ie the value of the CS is constant, and only changes the value of the EIP. Distance to another code segment is executed, CS / EIP must change. Shortness is different on the encoding, which is generally rarely specified in the assembly instruction, as long as the JMP target address is written, almost any assembler will adopt appropriate encoding according to the distance of the target address. Far transfer is rarely seen in the 32-bit system, which has been talked before, because there is enough linear space, a program rarely requires two code segments, and the useful system module is also mapped to the same address space.

JMP operands are naturally a target address, which supports direct addressing and indirect addressing. Indirect addressing can be divided into register indirect addressing and memory indirect addressing. Examples are as follows (32-bit system):

JMP 8E347D60; Direct address segment jump

JMP EBX; register indirect addressing: can only jump within segment

JMP DWORD PTR [EBX]; memory indirect addressing, segment jump

JMP DWORD PTR [00903DEC];

JMP Fward PTR [00903DF0]; memory indirect addressing, inter-section jump

Explanation:

In the 32-bit system, the full destination address consists of 16-bit segment selector and 32-bit offset. Since the width of the register is 32 bits, the register indirect addressing can only give 32-bit offset, so it can only be transferred in the segment. When the memory is indirectly addressed, the instructions are the valid address in square brackets, and the target address of the jump is stored on this address. For example, there is the following data at [00903DEC]: 7C 82 59 00 A7 01 85 65 9F 01

The memory byte is continuously stored, how do you determine how much as the target address? DWORD PTR indicates that the valid address indicates double word, so take

0059827C jump within the section. Conversely, Fward PTR indicates that the rear valid address is pointing to the 48-bit full address, so the 19F: 658501A7 is far away.

Note: In the protection mode, if the transfer involves the priority change, there is a series of complex protection checks now. I can learn from the future.

Condition transfer instructions JXX: You can only transfer in segments and only support direct addressing.

================================================= Call command Call:

The address of the Call is basically the same as JMP, but in order to return from a subroutine, the instruction presses the address of the next instruction following it before jump into the stack. If the call is called (the target address is a 32-bit offset), it is just an offset. If it is called during the inter-time call (the target address is 48 bit full address), it is also pressed into the full address of the next instruction. Similarly, there is a series of complex protection inspections if the metastatic changes involves priority.

The corresponding RETN / RETF instruction is returned from the subroutine. It acquires the return address from the stack (which is pressed in the Call instruction) and jumps to the address. RETN returns within the 32-bit offset section, RETF returns to the 48-bit full address process. Retn / f can also follow an immediate number as an operand, which is actually a number of specified numbers of the stack pointer ESP from the number of parameters (in words) from the stack upload to the subroutine. Discard parameters in the stack. The specific details here stay in the next story.

Although Call and RET are designed to work together, there is no necessity between them. That is, if you press the Push command to press a number in the stack, then execute RET, he will also put the number of crimped into the return address, and jump to the execution. This abnormal process transfer can be used as an anti-tracking means.

=================================================================================================================================================================================

Interrupt instruction INT N

In protection mode, this instruction will definitely be intercepted by the operating system. In a general PE program, this instruction has not been seen, and in the DOS era, the interrupt is an important way to call the operating system and the BIOS. The current program can call the Windows feature in the name of the name, such as Call USER32! GetWindowTexta. From a program perspective, the int instruction presses the current flag register to the stack, then press the full address of the next instruction into the stack, and finally retrieve the "Interrupt Descriptive Table" according to the operand n, try to transfer to the corresponding interrupt The service program is executed. Typically, all interrupt service programs are the core code of the operating system, which will inevitably involve priority conversion and protection checks, stack switching, etc., detail can see some advanced tutorials.

The corresponding interrupt returns the instead of the instruction IRET. It acquires the return address from the stack and sets the CS: EIP, then pop up the flag register from the stack. Note that the logo register value on the stack may have been changed by the interrupt service program, usually the carry flag C, is used to indicate whether the function is not completed. Similarly, IRET does not necessarily have to correspond to the int instruction, you can press the flag and address yourself on the stack, then execute the IRET to implement process transfer. In fact, multi-tasking operating systems often use this trick to implement task conversion.

Generalized interruption is a big topic, interested in consulting books for system design.

===================================================== 装 全 全 指指 l l , Les, LFS, LGS, LSS

These instructions have two operands. The first is a universal register, the second operand is a valid address. The command acquires 48-bit full pointers from the address, load the selector into the corresponding segment register, and load the 32-bit offset into the specified general register. Note In memory, the storage form of the pointer always 32-bit offset is in front, and the 16-bit selector is behind. After loading the pointer, you can use the DS: [ESI] to access the data indicted by the pointer.

==============================================

String operation instruction

Here, CMPS, SCAS, LODS, STOS, MOVs, INS, and OUTS, etc. These instructions have a common feature, that is, there is no explicit operand, and by hardware specifying DS: [ESI] to point to the source string, use ES: [EDI] to the target string, use Al / Ax / Eax to temporarily Save. This is the hardware specified, so it is necessary to set the corresponding pointer before using these instructions.

Every instruction here has three widths, such as CMPSB (byte comparison), CMPSW (word comparison), CMPSD (double word comparison), etc.

CMPSB: The first character string and the target string of the target string. If the phase is equal, the z mark is set 1. If it is inequal, the z mark is set 0. After the instruction is executed, ESI and EDI are automatically added to 1, pointing the next character of the source / target string. If you use CMPSW, a word is compared, ESI / EDI automatically adds 2 to point to the next word.

If you use CMPSD, a double word is compared, ESI / EDI automatically adds 4 to point to the next double word. (These instructions are the same at this point, no more details)

SCAB / W / D compares the values ​​in Al / Ax / Eax from one of the characters / word / double characters in the target string.

Lodsb / w / d put a character / word / double word in the source string to Al / AX / EAX

STOSB / W / D put direct in the direct in the directive string in the target string in Al / Ax / Eax

Movsb / w / d Put the characters / word / double words in the source string to the target string

INSB / W / D reads the character / word / double word from the specified port to the target string, the port number is specified by the DX register.

Outsb / w / d puts the characters / word / double characters in the source string to the specified port, and the port number is specified by the DX register.

The serial operation instructions are often used in conjunction with the repeated prefix REP and loop command LOOP to complete the operation of the entire string. The REP prefix and the LOOP instruction have hardware regulations to use ECX to do a loop counter. Example:

LDS ESI, SRC_STR_PTR

LES EDI, DST_STR_PTR

MOV ECX, 200

REP MOVSD

The above code is copied from SRC_STR to DST_STR. Details are: REP Prefix is ​​0, if otherwise, the MOVSD is executed, ECX is automatically reduced, then executes the second round check, execute ... Until the ECX = 0 will no longer perform MOVSD, the following instructions are executed.

LDS ESI, SRC_STR_PTR

MOV ECX, 100

LOOP1:

Lodsw .... (DEAL with value in ax)

Loop loop1

.....

Process 100 words from SRC_STR. Similarly, the LOOP instruction first judges whether the ECX is zero to determine if it is loop. Each cycle is automatically reduced.

Both REP and LOOP can be added to REPZ / RepNZ and Loopz / Loopnz. This is except for ECX, and uses the check zero flag Z. REPZ and LOOPZ to continue cycle, otherwise to exit the loop, even if ECX is not 0. RepNZ / LOOPNZ is the opposite.

- Author: saulia March 15, 2005, Tuesday 15:04 Reply (0) | Trackbacks (0). Add CASINO.

Preparation knowledge of assembly language - to the first contact assembler (2)

The number of assembly instructions can be data in memory, how to make the program to properly acquire the required data from memory is the addressing of memory.

Intel's CPU can operate in two addressing modes: real mode and protection mode. The former is outdated, and WINDOW is now 32-bit protection mode system, the PE file is basically running in a 32-bit linear address space So here only introduce the addressing method of 32-bit linear space.

In fact, the concept of linear addresses is very intuitive, imagine a series of bytes to be placed, the first byte number is 0, the second number bit 1, .... Or until 4294967295 (hexadecimal Ffffffffff, this is the maximum value that the 32-bit binary can be expressed. This already has 4GB capacity! It is enough to accommodate all code and data. Of course, this does not mean that you have so many memory. Physical memory The management and distribution are very complicated, and beginners don't care. In short, from the perspective of the program itself, it seems to be in that large memory.

In the Intel system, the memory address is always given by the "Segment Selector: Valid Address". Segment Selector Store In a certain segment register, the valid address can be given by different ways. Segment selector By retrieving the start address, length (also known as section restriction), particle size, access privilege, access nature, etc., etc., without rectifying these, as long as the segment selector can determine the nature of the segment, once The selector determines the segment, the base address of the valid address relative to the segment begins. For example, the data segment selected by the selector 1A7, the base address is 400000, and the 1A7 is loaded into the DS, it is determined to use the data segment. DS: 0 Point linear addresses 400000. DS: 1F5278 points to linear addresses 5E5278. We are in general, you don't need to see the starting address of the segment, just care about the valid address in this paragraph. At 32 In the bit system, the valid address is also indicated by 32 digits, that is, as long as one segment is sufficient to cover 4GB linear address space, why have you had different segment selectors? As mentioned earlier, this is for data Different nature access. The illegal access will produce an abnormal interrupt, which is the core content of the protection mode. It is the basis for constructing priority and multi-tasking system. Here there is a lot of deep things, beginners must first pay .

The calculation method of the valid address is: base number address * proportional factor offset. These quantities are measured relative to segment start addresses, and there is no relationship with the start address of the segment. For example, the base address = 100000, in-service = 400, scale factor = 4, offset = 20000, the valid address is:

100000 400 * 4 20000 = 100000 1000 20000 = 121000. The corresponding linear address is 400000 121000 = 521000. (Note, all the hexadecimal number).

The base can be placed in any 32-bit general register, and the inland address can also be placed in any universal register except ESP. The proportional factor can be 1, 2, 4 or 8. The offset is immediate. Such as: [ EBP EDX * 8 200] is an effective effective address expression. Of course, in most cases, it is not necessary to appear in many cases, in the case, unity, and unity.

The basic unit of memory is byte. Each byte is 8 binary locations, so the maximum number of each word energy conservation is 11111111, that is, the decimal 255. Generally, use hexadecimal comparison Convenient, because every 4 binary positions are just equal to 1 hexadecimal position, 1111111b = 0xFF. The byte in the memory is continuously stored, two bytes constitute a word (word), two words constitute a double word (DWORD). In the Intel architecture, in the Small Endian format, in memory, the high byte is behind the low byte. For example: the number of hexadecimal 803E7D0C, each two is one byte, in memory The form is: 0C 7D 3E 80. It is normal in the 32-bit register. If EAX is 803E7D0c. When our form address points to this number, it is actually pointing to the first byte, ie 0c. We can Specifying access length is byte, word or double word. Suppose DS: [EDX] points to the first byte 0c: MOV Al, Byte Ptr DS: [EDX]; put byte 0C in Al

MOV AX, Word PTR DS: [EDX]; deposit the word 7D0C into AX

MOV EAX, DWORD PTR DS: [EDX]; deposit double word 803E7D0C in EAX

In the properties of the segment, one is the default access width. If the default access width is double word (this is often in the 32-bit system), then the byte or word is visible, you must use Byte / Word PTR display Formulated.

Default segment selection: If there is only a valid address as the offset in the instead of the instead of indicating which segment is specified:

If eBp and ESP are used as the base or in the address, it is considered to be in the segment determined by the SS;

Other situations are considered to be in the DS determined segment.

If you want to break this rule, you must use the segment beyond prefix. For example, as follows:

MOV EAX, DWORD PTR [EDX]; DS: [EDX] points to EAX by default

MOV EBX, DWORD PTR ES: [EDX]; Use ES: Segment Beyond Prefix, send ES: [EDX] to EBX

Stack:

The stack is a data structure, which is strictly called "stack." "Heap" is another similar but different structure. SS and ESP are hardware support for Intel's stack of this data structure. The PUSH / POP instruction is a specific operation specifically for the stack structure. SS specifies a segment as a stack, and ESP points out the current stack top. The PUSH XXX instruction works as follows:

Dump the value of the ESP 4;

Store XXX into the memory unit pointing to SS: [ESP].

In this way, the value of the ESP is reduced by 4, and SS: [ESP] points to the newly pressed XXX. So the stack is "in the long", extension from the high address to the low address direction. Pop YYY instructions do the opposite operation, send the double word pointing to the SS: [ESP] to YYY specified register or memory unit, and then add the value of the ESP 4. At this time, it is considered that this value has been popped up, no longer on the stack, because it is still temporarily present in the original stack top position, but the next PUSH operation covers it. Therefore, the data in the memory cell below the stack is considered undefined.

Finally, there is a fact that the assembly language is the machine, the instruction and machine code are basically one or one, so their implementation depends on the hardware. Some seemingly reasonable instructions do not exist, such as:

MOV DS: [EDX], DS: [ECX]; Cannot be transferred directly between memory cells

MOV DS, 1A7; segment registers cannot be directly assigned

MOV EIP, 3D4E7; not directly to the instruction pointer.

- Author: saulia March 15, 2005, Tuesday 15:02 Reply (0) | Trackbacks (0). Add CASINO.

Preparation knowledge of assembly language - for the first time contact assembler (1)

Hardware knowledge such as compilation language and CPU and memory, ports are connected. This is why the assembly language has no versatility. Simply talk about basic knowledge (for Intel X86 and its compatible machine) ======= =====================

The x86 assembly language instructions are the operation objects are registers, system memory, or immediate numbers on the CPU. Some instructions have no operands, or they look missing operands, in fact, this instruction has an internal operation object, such as a PUSH directive, It must be the memory operation specified for the SS: ESP, and the CDQ operation object must be EAX / EDX.

In assembly language, the register is accessed with the name. The CPU register has several categories, which have different uses:

1. Universal register: EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP (this is universal, but it is rarely used in addition to stack pointers) These 32 bits can be used as a variety of purposes, but Every one has "Expertise". EAX is "Accumulator), which is the default register of many addition multiplication instructions. EBX is a" base address "register, store the base address when memory addressing. ECX It is a counter, which is a replicate counter (REP) prefix instruction and the memory instruction of the LOOP instruction. EDX is ... (forgot .. Haha) but it is always used to place the remainder generated by any division. These 4 registers The low 16 bits can be accessed separately, with AX, BX, CX, and DX. AX can also access the low 8-bit (Al) and 8 bits (AH), BX, CX, and DX separately. Function return value It is often placed in EAX. ESI / EDI is called "source / destination" (Source / Destination INDEX), because in a lot of string operation instructions, DS: ESI points to the source string, and ES: EDI points to the target string. EBP is "Base Pointer", it is most often used as a "frame pointer" (Frame pointer "called by advanced language function. When cracking, you can often see a standard function start code: Push EBP Save the current EBP MOV EBP, ESP; EBP is set to the current stack pointer SUB ESP, XXX; reserved XXX bytes to function temporary variables. ... so, EBP constitutes a framework of the function, on the EBP It is the original EBP, returned address and parameters. The following is a temporary variable. The function returns MOV ESP, EBP / POP EBP / RET. ESP is specifically used as a stack pointer. 2. Segment register: CS (Code Segment, Code segment) Specifies the currently executed code segment. The EIP (INSTRUCTION POINTER, the instruction pointer) points to a specific instruction in this segment. CS: EIP Which instruction is pointed to the CPU. Generally only use JMP, RET, JNZ, Call and other instructions to change the program process without having to assign them directly. DS (Data Segment, Data Section) Specify a data segment. Note: In the current computer system, the code and data have no essential differences, all of which are a string of binary The difference is only how you use it. For example, the Section of the CS is always used as a code, and it is generally not modified by the address specified by the CS. However, you can apply for a data segment descriptor "alias" for the same segment to access / modify through the DS. Self-modifying code is commonly done. ES, FS, GS is an auxiliary segment register, specify additional data segments. SS (STACK segment) specifies the current stack segment. ESP points out the current stack top in this segment. All PUSH / All POP series instructions operate only the addresses indicated by SS: ESP. 3. Sign Register (EFLAGS):

This register has 32 bits, combines each system flag. EFLAGS is generally not integrated, but only interested in a single sign. Commonly used flags are: carry mark C (carry), borrowing in addition to incorporation or subtraction Time 1, otherwise it is 0. Zero flag Z (ZERO), if the operation result is 0, it will be 0 symbol bit S (SIGN), if the result of the calculation result is 1, the bit is also placed 1. overflow Sign o (overflow), if the (with the symbol) operation is exceeds the scope, then the JXX series instruction is based on these flags to determine whether to jump, thereby implementing the conditional branch. To note that many JXX instructions are waiting The price, corresponding to the same machine code. For example, JE and JZ are the same, all Z = 1 is jumping. Only JMP is unconditional jump. The JXX instruction is divided into two groups, which are used for unsigned operations and band, respectively. Symbol operation. "XX" behind JXX has the following letters: no symbolic operation: with symbolic operation: A = "above", indicating "higher than" g = "greater", indicating "greater than" b = "below", indicating " Lower than "L =" LESS ", indicating" less than "c =" carry ", indicating" carry "or" borrow "o =" overflow ", indicating" overflow "S =" SIGN ", indicating" negative "universal symbol : E = "equal" means "equal to", equivalent to z (zero) n = "not" means "non", that is, the flag is not set. Such as JNZ "If Z is not set, jump" z = "ZERO ", With E. If you think about it carefully, you will find ja = jnbe, jae = JNB, JBE = JNA, JG = JNLE, JGE = JNL, JL = JNGE, .... 4. The port port is straight and External equipment communication place. After the peripheral access system, the system will map the peripheral data interface to a specific port address space, which read data from the port is to read data from the peripheral, and write data to the peripheral is to port. data input. Of course, this must follow peripheral work. The address space of the port is independent of the memory address space. The system provides access to 64K 8-bit ports, numbered 0-65535. Adjacent 8-bit ports can be formed into a 16-bit port, adjacent 16-bit ports can form one 32-bit port. The port input and output is implemented by the instruction IN, OUT, INS, and OUTS, and specific reference language books.

- Author: saulia March 15, 2005, Tuesday 15:01 Reply (0) | Trackbacks (0). Add CASINO.

Easily use your own callback function

The callback function is a very useful, and it is also very important concept. When a certain event occurs, the system or other function will automatically call a function of your defined. The callback function is used in Windows programming, such as the Hook callback function: MouseProc, getMsgProc, and EnumWindows, DrawState callback functions, there are many system-level callback processes. This article is not prepared to introduce these functions and processes, but talk about some experiences in implementing their own callback functions. The reason for producing this callback function is because now use VC and Delphi hybrid programming, with a DLL program written by VC to make some time for more time, after work is completed, you need to notify the use of DLL applications: Some events Already completed, processes the subsequent part of the event. Start thinking about using synchronous objects, files, messages, etc. to implement DLL functions to the application, and then suddenly thinks that you can write a function in the DLL when you need to handle follow-up, etc. I.e. So I started and wrote the original shape of a callback function. Test one in VC and Delphi: Declare the callback function type. VC version typef int (WinAPI * PfCallback) (INT Param1, Int Param2); Delph version pfCallback = function (param1: integer; param2: integer): integer; stdcall; actually declares a return value INT, incoming parameters The pointer for the pointing function of two INTs. Since the C and Pascal compilers may be inconsistent with the processing returned by the parameters and the function, the function type uses WinAPI (WinAPI Macro Exhibition is __stdcall) or STDCALL unified modification. 2: Declaration callback function protocol declaration function original VC version int WinAPI CBFUNC (int Param1, int param2; Delphi version Function CBFUNC (param1, param2: integer): integer; stdcall; The above function is a global function, if you want to use a class The function is as a callback function, and the class function is declared as a static function. Three: The callback function calls the caller call the callback function. I put it in the DLL, which is a very simple VC generated Win32 DLL. And use the DEF file to output its function name TestCallback. To achieve the following: PFCALLBACK gCallBack = 0; void WINAPI TestCallBack (PFCALLBACK Func) {if (Func == NULL) return; gCallBack = Func; DWORD ThreadID = 0; HANDLE hThread = CreateThread (NULL, NULL, Thread1, LPVOID (0), & ThreadID); Return;} This function is saved to save the incoming PFCallback func parameters and start a thread. Declare a function pointer PFCallback GCallback saves the incoming function address.

Four: How to use the callback function: TestCallback function is called, start a thread, as a demonstration, the thread is delayed, and print the thread runs on the screen. The code of this segment is also in the DLL Implement Ulong WinAPi Thread1 (LPVOID PARAM) {Tchar Buffer [256]; HDC HDC = Getdc (hwnd_desktop); int steel = 1; msg msg; dword starttick; // a delay cycle for (; Step <200; step ) ) {StartTick = gettickcount (); / * This section is handed over part of the running time for the system to handle other transactions * / for (; gettickcount () - StartTick <10;) {IF (PeekMessage (& MSG, NULL, 0, 0, PM_NOREMOVE)) {TranslateMessage (& MSG); DispatchMessage (& MSG);}} / * Prints the running situation to the desktop, this is the most like-to-dry thing when the vcbear debugger * / sprintf (buffer, "running% 04d", Step); if (HDC! = N ULL) TextOut (HDC, 30, 50, Buffer, Strlen);} / * Delayed callback function * / (* gcallback) (Step, 1); / * End * / :: releasedc HWND_DESKTOP, HDC); Return 0;} 5: Everything has a project with VC and Delphi, write a callback function

VC Edition Int WinAPI CBFUNC (Int Param1, Int Param2) {Int Res = Param1 Param2; Tchar Buffer [256] = ""; Sprintf (Buffer, "Callback Result =% D", RES); MessageBox (null, buffer, "Testing", MB_OK; // Demo the callback function called Return Res;} Delphi version Function CBFUNC (PARAM1, PARAM2: Integer): Integer; Begin Result: = param1 param2; tform1.edit1.text: = INTOSTR (Result ); / / Demo the callback function is called END; use a static connection method to connect the exit function TestCallback in the DLL, add Button in the project (for Delphi engineering, you need to put an edit control on Form1, the default name Edit1) . Response ButtonClick Event Call TestCallbackTestCallback (CBFUNC) // Function Parameter CBFUNC returns immediately after calling the address function of the callback function, the application can go at the same time. Now you can see the display string on the screen, indicating that the thread created in the DLL is working properly. After a while, the thread delay part ends, the VC application pops up MessageBox, indicating that the callback function is called and displays the result of the PARAM1, PARAM2 operation, and the text in Delphi's program edit control is rewritten into param1, param2 operation. result. It can be seen that the programming mode using the callback function can be transmitted according to different requirements, or the original shape of various callback functions can be defined (but also need to change the parameters of the callback function and the return value) to implement a variety of callback event processing. It can make the program's control flexible and more equivalent, a highly efficient, clear program module. Especially useful in some asynchronous or complex program systems - you can concentrate on the business process and technical features of the module core in a module (such as DLL), the external extension function gives only a callback function interface, by calling In the way, other modules pass the callback function address, seamlessly handle the subsequent processing to another module, handle it in a customized manner. This example uses the way the callback function is called after the multi-thread delay in the DLL, but in order to highlight the effect of the callback function, it can be delivered to the function address as long as it is in this process. Go, as a callback function is used. This kind of programming mode is very simple. One: That is to show the function as a pointer an address to call, there is no other complicated thing, just a small skill in the programming. As for the callback function mode, how much benefits can you bring to you, just see if you are using, how to use this programming mode.

- Author: saulia March 15, 2005, Tuesday 14:19 Reply (0) | Trackbacks (0). Add CASINO.

Windows interrupt programming

I. Foreword Windows provides powerful features and friendly graphical user interface (GUI), which makes it not only widely used as a support platform for management transaction, but also is concerned by engineers in the industrial sector. However, Windows 3.1 is not based on priority to scheduling tasks, which cannot respond immediately to external event interrupts, which cannot meet the requirements of real-time event processing and real-time control applications in industrial application environments. Therefore, how to handle external real-time events in a Windows environment has always been concerned with technical personnel, especially in real-time engineers. At present, existing methods can mostly use the multi-tasking kernels in the internal mutation, such as Windows real-time control packages, etc., and the IRMX real-time operating system uses Windows3.1 as a task of its task. For large engineering projects, developers can use the purchase real-time software and then integrate ways. For small and medium-sized projects, it is not economical from investment. How to find a concise approach to deal with external real-time events still seems necessary. This article first explains the WINDOWS message mechanism and interrupt mechanism, and then combines the DPMI interface to give a design method of interrupt programs in the protection mode to handle external real-time events. The actual operation shows that this method has a simple, practical, reliable characteristic and can also be operated in Win95. Second, Windows's message mechanism Windows is a message-driven system. The Windows message provides the application between the application and the application, and the application communicates with the Windows system. The function to be implemented by the message is triggered by the message and is done by the response and processing of the message. There are two messages in the Windows system, one is the system message queue, the other is the application message queue. All input devices of the computer are monitored by Windows. When an event occurs, Windows first places the input messages in the system message queue, and then copy the input message to the corresponding application queue "" Message loop in the application " In its message queue, each message is retrieved and sent to the corresponding window function. An event occurs, the window function to the process you must undergo. It is worth noting that the non-charm of the message is, that is, regardless of the urgentity Slow, always queue up by arrival (except for some system messages), this makes some external real-time events may not have timely processing. Third, Windows protection mode and interrupt mechanism 1.Windows protection mode protection mode finger It is a linear address being generated by a selector, which points to a certain item in the description table; in real mode, directly addressed by a segment / offset pair. 80386 (486) CPU prosecution Mode capability includes a 64K virtual address space and a 4G segment size. The Windows3.1 is different, it supports standard mode and enhancement mode. The standard mode is for 286 machines, and the scope of the unpaid Ben. The enhanced mode is 386 For the above CPU, Windows is using the protection mode to break the LM barrier and perform simple memory protection. It uses the selector, descriptor, and descriptor table control to access the location and segment of the specified memory. Descriptor table includes a global descriptor Table partial descriptor table, interrupt descriptor table. Protection mode has many different modes. The significant difference is that the mechanism of accessing the memory is different. 2. Interrupt mechanism (1) Real mode interrupt To make it easy, let's review the real model first Interrupt. In real mode, the interrupt vector table IVT plays a considerable role. Whether it comes from an interrupt from an external hardware or an internal soft interrupt INTN, the same response is generated in the CPU. 1CPU Current instruction pointer register (IP ), Code segment register (CS), the flag register is pressed into the stack. 2 Then the CPU uses the n value as the index of the interrupt vector table IVT, and finds the far address of the service routine in the IVT. 2CPU will be stored in this far CS: In the IP register, and start the execution routine. 4 Interrupt routines always end with the IRET instruction.

This instruction makes three values ​​in the stack and fill in the CS, IP, and flag registers, and the CPU continues to perform the original instruction. (2) The protection mode interrupt protection mode interrupt process is similar to the real mode interrupt process, but it no longer uses the interrupt vector table IVT, and the interrupt descriptor table (IDT) is used. It is worth mentioning that the Windows runtime IVT still exists, the application does not use it, Windows is still used, but the meaning is different '(1) IVT structure: IVT is above the RAM 0000: 0000, 1024 words occupied Section. It is still set by the BIOS boot routine, fills in the RAM by DOS. 2IDT Interrupt Descriptor: In the protection mode, the Windows operating system is established for the implementation of the interrupt mechanism, i.e., an interrupt descriptor table IDT. The table is used to save the linear address of the interrupt service routine, which is a true 24-bit or 32-bit address, no segment: offset value structure. The interrupt descriptor table can contain up to 256 cases, please see [3] for details. The IDT structure is shown in Figure 2. 2 When the interrupt or abnormality occurs, the processing process is stored in the current CS; IP value, and flag register value. The saved content also includes the value of the other internal registers of the CPU, as well as information about the tasks being executed (if task switches must be switched). After the CPU is trying to obtain the interrupt vector, it is used to find the service routine remote address in the IDT for the index value, and then the control is transferred to the service routine of the location. This is different from the real mode to IVT. The protection mode uses the IDTR register allocation and positioning the IDT interrupt descriptor table. IDT is movable in memory, and is just opposite to IVT. The IDT interrupt descriptor table from the decisive role in Windows. Understand the interrupt mechanism of Windows protection mode. It helps us understand the design of the interrupt service program, the key is how to put the address of the service routine into the IDT interrupt descriptor table. When interrupt occurs, how to protect the breakpoint address and the CPU register value, how to recover the protected value at the end of the interrupt. The Windows system itself does not provide an API that implements the above functions, while the DOS protection mode interface DPMI is equipped with the above functions. Below we first introduce the DPMI interface, then based on it implements the design of the interrupt service program under Windows. Fourth, DOS Protection Mode Interface DMPI Windows also supports a set of special DOS services, called DOS protection mode interface DPMI, composed of some int2fh and int31h services. It enables applications to access the expansion memory of the PC series computer while maintaining the protection of the system. DPMI defines a new interface through software interrupt 31h, so that the application of the protection mode can use it to assign memory, modify the descriptor, and call real mode software. Windows provides DPMI services for your application. That is, Windows is a host (Host) of DPMI, the application is a customer (Client), which can be called DPMI service via INT31H. INT 31H itself provides versatile. Its interrupt management service allows protection mode to intercept the real mode interrupt and hook the processor exception. Some services can work with the DPMI host to maintain the virtual interrupt flag of the application. The protection mode interrupt vector can be hooked with INT31H to process external real-time events in an interrupt mode. With int 21h, function 0205H: Set the protection mode interrupt vector, place the address of the specific interrupt protection mode handler into the interrupt vector. Call mode: AX = 0205H, BL = interrupt number, CX: (e) DX = Interrupt handler selector: offset value.

Returns: Perform success CF = Clear, perform failed CF, set. The timing of hosing / knocking interrupt vector is important. The main window will transfer its WM-CREATE message for the first time, which is the best time to hang the interrupt vector. Need to solve the vector when you quit, otherwise Windows may crash. After receiving WM_DESTROY, the window is being received, it is the most suitable. The knot vector can be saved with INT35H, 0204H function, and use INT35H, 0205h to recover when exiting. 5. Programming has been supported by DPMI. We can easily handle real-time events in industrial processes such as data acquisition, serial communication. The serial communication implemented by the Windows 3.1 platform is interrupted as an example, and the compilation and implementation of the interrupt program is explained. For ease of reference, the detailed code is given. Development Platform BC3.1 / BC4.5, itself supports 0.9 version of DPMI without running other software supporting DPMI. Programming language C, can be compiled with C . Initialize the COM1, 9600 baud rate, each character 8bits, 1 stop bit, interrupt reception, query transmission.

// windows asy COmmunica60n // by Li Xiumi98 // last modified on June25,1996 #include #include void interrupt far DataReceive (); void interrupt far (* old_vector) (); unsigned char dataCom_r [1024], datacom_s [1024]: int inflag = 0; unsigned int s8259; int InitCom1 () {s8259 = inportb (0x21); outportb (0x21, s8259 & 0xe8); outportb (0x3fb, 0x83); outportb (0x3f8, 0x0C); OUTPORTB (0x3f9, 0x00); OUTPORTB (0x3FB, 0x03); OUTPORTB (0x3FC, 0x08); OUTPORTB (0x3f9, 0x01); Return 1;} void interrupt far datareceive () {static int i = 0; char rechar = 0; rechar = inportb (0x3f8); if (inflag == 0) {if (rechan! = 'S' && i == 0) {i = 0; goto L1;} Datacom_r [i ] = rechar; if (Rechar) == E ') {inflag = 1; i = 0;}} L1: OUTPORTB (0x20, 0x20);} voidin (void) {asm {cli; MOV AX, 204H MOV BL, 0CH INT 31H STI} OLD_Vector = MK_FP (_CX, _DX); ASM {CLI MOV AX, 205H MOV BL, 0CH MOV CX, SEG DATARECEIVE MOV DX, OFFSET DATARECEIVE INT 31H STI} INITCOM ();} void restore_comm (void) {OUTPORTB (0x21, s8259) AS M {CLI MOV AX, 205H MOV BL, 0CH MOV CX, SEG OLD_VECTOR MOV DX, OFFSET OLD_VECTOR MOV DX, OFFSET OLD_VECTOR INT 31H STI}} The WM_CREATE message is transferred when the window is created, and INITCOM () is called. When the main window is closed, when the WM_DESTROY message is received in the main window, the restore comm () is called to restore the original state. This initializes the serial port, when the interrupt service routine is set, the communication event occurs, immediately jump into the interrupt subroutine, and cross the system's message queue to achieve the purpose of implementing the communication event in real time. The data processing module can access the global data communication buffer to get real-time data through global flags F1, 8. This implementation is characterized by real-time power than the message-based Windows communication API implementation because it exceeds the two-pole message mechanism for the Windows system, and the above program has been applied in the actual system. Run three Windows tasks under Windows3.1 support, server Server (with real-time serial communication, multiple network data subsidiary services,), customer client, FoxPro database system. The entire system is working well.

Switch to the Win95 platform, the system is also working well. - Author: saulia March 15, 2005, Tuesday 14:15 Reply (0) | Trackbacks (0). Add CASINO.

The principle of hook monitoring of Windows keyboard events and its application technology

The Windows message processing mechanism provides a function of monitoring various reverse modulation functions (hook) in order to monitor the various event messages of the system in the application. This hook function (hook) is similar to the interrupt driver, and there is a plurality of reverse modulation functions on the hook to form a hook function chain. The various messages generated by the system are first sent to various mount functions, and the mount functions are monitored, modified, and controlled according to their respective functions, and then return control or transfer the message to the next hiking function. Window function. Although this anti-modulation function on the Window system will be slightly affected by the system's operating efficiency, it is very useful in many occasions. It can achieve a good effect by reasonably utilizing the hook function monitoring mechanism that utilizes the keyboard event. . First, the filter function on the WINDOWS keyboard event is monitored, the filter function can be mounted under WH_CallWndProc window function filter function wh_CBT computer training filter function wh_debug debugging filter function wh_getMessage Get Message filter Filtering function wh_hardware hardware message filtering function message replay function WH_JOURNALPLAYBACK filter function WH_JOURNALRECORD message recording function filter function filtered WH_MSGFILTER WH_MOUSE mouse message system message filter function WH_SYSMSGFILTER WH_KEYBOARD filter function keyboard function keyboard filter wherein the filter function is the most common and useful type of filter function, regardless of which type of Filter functions, the basic methods of their hill are the same. When the Window calls the mounted rebound, the function of the hook-chain first is always called, so the keyboard hook function must be used to use the function setWindowsHooKex () to list it in the function chain. As for whether the message passes to the functional chain is determined by each specific function function, if the message needs to be traditionally given to the next function, you can call the CallNextHooKex () of the API function, if not transferred, returned. The mount function can be a global function used to monitor all thread messages, or a partial function of a single thread can also be monitored separately. If the mount function is a partial function, you can put it in a .dll dynamic link library, or in a partial module; if the mount function is globally, then you must put it in one .dll dynamic link library in. The mount function must be declared in the following formats, with the keyboard hook function as an example: int FAR Pascal KeyboardProc (int Ncode, Word WPARAM, DWORD LPARAM) where KeyboardProc is the name of the function name, which must be in the module definition file. Use the exports command to explain; NCODE determines whether the mount function is processed; WPARAM and LPARAM are specific message content. Second, the installation and download of the keyboard event mount function can utilize the function setWindowsHooKex () in the program, and the filter function must be pointed out when the function must indicate the type of the mount function, the entry address of the function, and the function of the function are global. Still partial, the specific call format of the mount function is as follows: setWindowsHookex (iProc, hinst, icide) where ITYPE is the type of mount function, the keyboard type is wh_keyboard, iProc is the hosted function address, Hinst is a hougap function link Library instance handle, iCode represents a global function for monitoring code -0. If the hosted function needs to pass messages to the next filter function, you need to call a callNextHooKex () function before the mount function returns. When you need to download the mount function, you can only call a UNHOOKWINDOKEXEX (iProc) function. .

If the function is global, it must be placed in a .dll dynamic link library, then the function call method can be the same as those of other ordinary .dll functions: 1. Direct function name or serial number in the DEF definition file Description: Exports WEP @ 1 ResidentName INITHOOKSDLL @ 2 InstallFilter @ 3 KeyboardProc @ 4 Document Description Format is: Link Book Name. Function Name (in this example is Keydll.KeyboardProc). 2. Use the function to use the function directly: First use LoadLibrary in the application (LPSTR "Link Link Name" to load the dynamic link library, and obtain the load library module handle Hinst, then use GetProcadDress (Hinstance Hinst, LPSTR) "Function Process Name" Gets the function address, then call the address directly, before the program ends the function freeibrary () release the loaded dynamic link library. 3. Using the input library .LIB method uses the Implib.exe program to establish a corresponding input library while establishing a dynamic link library .Lib, then adding the input library directly in the project file. Third, the implementation of the Windows Hook Monitoring Function Steps Windows Hook Functions are only placed in the dynamic link library DLL to implement all event monitoring functions. The basic method of the hook monitoring function is formed in .dll and its basic structure is as follows: 1, first declare the variables and processes in the DLL; 2, then prepare the DLL main module libmain (), establish a module instance; 3, establish a system exit DLL mechanism WEP () Function; 4, complete the DLL initialization function INITHOKSDLL (), pass the main window program handle; 5, prepare hooks installation and download functions installfilter (); 6, prepare the hook function keyboardProc (), set the monitoring function, and confirm Tune a hook function or return to a Windows application. 7. In the Windows main program, it is necessary to initialize the DLL and install the corresponding hook function, which is responsible for communication with the main programming by the hook function; 8, the download function is removed by the download function when the monitor is not required. Fourth, the application technology of the keyboard hook monitoring function is currently two special buttons on the standard 104 keyboard, which use the Window program logo and the mouse drop-down list, which is temporarily called micro left mock and micro right, respectively. The former is used to simulate the left mouse button to activate the start menu, the latter used to simulate the right mouse button to activate the property menu. These two special buttons only raise the Click procedure immediately after pressing, and does not use the other button to combine. Since the button is divided into a button in the Windows system, it is difficult to flexibly define its own dedicated shortcuts, such as developing .IME and other applications, it is difficult to find a function button that is not conflict with other application other applications such as Word 8.0. . If the two special buttons in the standard 104 keyboard are dedicated buttons such as the analog Ctrl and Alt, they can freely set the dedicated function keys in their own applications to implement various functions for the application. Shortcuts provide flexibility. Under normal circumstances, the Windows Keyboard Event Driver does not explain the messages of the two buttons, which must be used to use the hook monitoring function of the keyboard event to implement its specific function. The method is as follows: 1. First, prepare the next simple dynamic link library program and compile into a DLL file.

#include "windows.h" int FAR PASCAL LibMain (HANDLE hModule, UINT wDataSeg, UINT cbHeapSize, LPSTR lpszCmdLine); int WINAPI WEP (int bSystemExit); int WINAPI InitHooksDll (HWND hwndMainWindow); int WINAPI InstallFilter (BOOL nCode); LRESULT CALLBACK KeyHook (int nCode, WORD wParam, DWORD lParam); static hANDLE hInstance; // global handle static HWND hWndMain; // main window handle static int InitCalled = 0; // initialization flag static HHOOK hKeyHook; FARPROC lpfnKeyHook = (FARPROC) KeyHook; BOOL HookStates = FALSE; int FAR PASCAL LibMain (HANDLE hModule, UINT wDataSeg, UINT cbHeapSize, LPSTR lpszCmdLine) {if (cbHeapSize = 0!) UnlockData (0); hInstance = hModule; return 1;} int WINAPI WEP (int bSystemExit) {return 1;} int WINAPI InitHooksDll (HWND hwndMainWindow) {hWndMain = hwndMainWindow; InitCalled = 1; return (0);} int WINAPI InstallFilter (BOOL nCode) {if (InitCalled == 0) return (-1); IF (ncode == true) {hkeyhook = setwindowshookex (wh_keyboard, (hookproc) lpfnkeyhook, hinstance, 0); hookstates = true;} else {UnHookWindowsHookex (HKEYHOOK) Hookstates = false;} Return (0);} Lresult Callback Keyhook (int Ncode, Word Word WPARAM, DWORD LPARAM) {static bool msflag = false; if (ncode> = 0) {if (hookstates == true) {IF (wparam == 0xff) || //win3.x Under button value (WPARAM == 0x5b) || (wparam == 0x5c)) {// Win95 button value IF ((i == 0x15b) || (i == 0x15C)) {// button Press to process MSFLAG = true; PostMessage (hwndmain, 0x7fff, 0x1, 0x3L);} else if ((i == 0xc15b) || (i == 0xc15c)) {// button Lift the processing MSFLAG = false; PostMessage (HWndmain, 0x7FFF, 0x2, 0X3L);}}}} Return ((int) CallNexthooKex (HKEYHOK, NCODE, WPARAM, LPARAM);} The program's main function is to monitor keyboard button messages Convert two special buttons Micro Press and Lift the message into a custom type message, and send custom messages to the application main window function.

2. After the window is created in the application main function, call the IITHOOKSDLL () function to initialize the dynamic link library and pass the application main window handle to the link library, and then call the installfilter () function Mount the key disk event to monitor the callback function. INITHOOKSDLL (HIMEWND); // Initializing DLL InstallFilter (TRUE); // Install the keyboard callback function 3, when the application main window function processes a custom message, saves the state of the Micro button, and is judged when the combined button processing is used. Switch (IMESSAGE) {case 0x7fff: // Custom Message Type IF (LPARAM == 0x3L) {// Set the status IF of the Micro button (wparam == 0x1) microflag = true; Else If (wparam == 0x2) microflag = False;} Break; 4, when the button combination is performed, first determine if the Micro button is pressed, and then the judgment processing of other buttons. Case WM_KeyDown: // Press to process if (microflag == true) {// micro button Press IF ((Byte) Hibyte (WPARAM) == 0x5b) {// micro "[" combination key ..... .// button function} else if ((byte) {// micro "]" combination key ... // button function processing}} Break; 5, when the application When exiting, you should pay attention to the download keyboard monitor function, that is, call the InstallFilter (false) function once. 6. Use the methods provided herein to set your own application function buttons, while ensuring that the program function button does not conflict with other systems, the existing resources in the system are effectively utilized, and the application function is flexible while implementing the application function. Various functional calls provided in the system. - Author: saulia March 15, 2005, Tuesday 14:12 Reply (0) | Trackbacks (0). Add CASINO.

DLL programming technology and applications under Windows

Summary:

This paper introduces the basic method and application of DLL technology in Windows programming, which gives all source code for two practical DLLs of direct memory access and port I / O.

Keywords: DLL Windows programming memory access I / O

I. Introduction

Since Windows provides unprecedented standard user interfaces, graphics processing capabilities and simple flexible operations for microcomputers, most of the programming people have turned to Windows programming. In the programming task of the actual application system designed by many users, it is often necessary to implement access to hardware resources and memory resources, such as port I / O, DMA, interrupt, direct memory access, and more. If you have a DOS program, this is a lifted thing, but it is more difficult to prepare a Windows program, especially the procedure in the WindowsNT environment.

Because Windows has the characteristics of "unrelated to the device", it is not advocated to deal with the bottom of the machine. If you use the Windows API function or I / O readout instruction to access and operate, the program runs often generates a protection mode error or even Cancer, more serious situations can cause the system to crash. So how to solve the above problems under Windows? It is one of the good ways with DLL (Dynamic Link Libraries) technology.

DLL is the most important component of Windows, many new features in Windows, new features are implemented by DLL, so master it, it is very important. In fact, Windows itself is composed of many DLLs. Its most basic three-large forming module KERNEL, GDI and user are DLL, and all of its library modules are also designed as a DLL. Any system file that is .dll, .drv, .fon, .sys, and many .EXE is DLL. If you open the Windows / System directory, you can see a lot of DLL modules. Although the DLL runs under Ring3 priority, it is still a simple way to implement hardware interfaces. DLL can have its own data segment, but there is no own stack, use the same stack mode as the application called it, reduce the inconvenience of programming design; at the same time, only one instance in memory, make it efficient and economical Use memory; DLL implementation code package makes the program simple and clear; there is also a biggest feature, that is, DLL's preparation is independent of specific programming language and compiler, as long as the DLL development specification and programming strategy, and arrange The correct call interface, regardless of the DLL prepared in the programming language, is versatile. For example, the DLL program compiled in BC31 can be used in a variety of locales such as BC, VC, VB, Delphi. The author compiled in the BC31 environment to direct memory access and port I / O two DLLs in the BC31, which is well running in the application of multiple homemade systems. Second, DLL establishment and call

The establishment and calling method of the DLL has a detailed introduction in many information, in order to save space, only some of the main summary here.

1.DLL establishment

Regarding the establishment of the DLL, it is an indispensable and must be mastered by the following aspects.

Entrance function libmain ()

Like WinMain () in the C program, Windows must perform libmain () functions each time the DLL is loaded, mainly used to make some initialization work. The usual form is:

Int Far Pascal Libmain (Hinstance Hinstance, Word Word Word WHEAPSIZE, LPSTR LPSZCMDLINE)

{

IF (WHEAPSIZE! = 0) // Make local heap, data segment can be moved

UNLOCKDATA (0);

// Unlock data segment

/ * Some user necessary initialization works * /

Return 1; // Initialization success

}

Exit function WEP ()

When Windows uninstall the DLL from the memory, call the corresponding export function WEP (), mainly do some cleaning work, such as the release of the memory resources; discard some strings, bitmaps and other resources; turn off the open file, etc..

Custom output function

In order to remotely call the application in different memory segments, the custom output function must be defined as a remote function (using the FAR key) to prevent accidental results to use the short-range pointer; at the same time, plus the pASCAL keyword The running speed of the program can be accelerated, so that the code is simple and efficient, and the program's running speed is improved.

Output function

In the DLL module definition file (.def) is listed by the exports statement on the output function one by one. E.g:

Exports WEP @ 1 ResidentName

// ResidentName improves DLL efficiency and processing speed

Portin @ 2

Portout @ 3 // Usually add a series number of all output functions

Use the _export keyword to use the _export keyword in the description of each output function.

One of the above two methods is optionally, it is not repetitive. The following two instances use two different drawings, please pay attention.

2. DLL call

When loading the DLL, Windows looks for the order of the corresponding DLL as follows:. Current work Dry.

Windows directory; getWindowsDirectory () function provides the path name of this directory.

Windows system catalog, system subdirectory; call the getSystemDireTory () function to get the path name of this directory.

DOS's path commands all directories in the Ruspe.

All directories in the list of images in the network.

Calling method of output function in the DLL module:

No matter what language is used to call the compiled DLL, there are basically two call modes, namely static call modes, and dynamic call mode. Static call mode is completed by the compilation system to the DLL load and the DLL uninstalled encoding (if any other program is used using the DLL, Windows reduces the application record of the DLL 1 until all related programs end the DLL Release it when you use it), simple and practical, but not flexible enough, you can only meet the general requirements. The dynamic call mode is to load and unload the DLL by the programmer to reach the purpose of calling the DLL, which is more complicated, but more efficiently uses memory, is an important way to prepare a large application. Specifically, the following method can be used. In the application module definition file, the function name to call the DLL is listed with the imports statement. Such as:

Imports

Memorydll.MemoryRead

Memorydll.Memorywrite

Let the application run with the DLL module dynamic link

Use loadLibrary to load the DLL, and then use the getProcAddress function to check the address of its output function, get its pointer to call. Such as:

Handle Hlibrary;

FarProc LPFUNC;

INT portvalue;

Hlibrary = loadingLibrary ("portdll.dll");

// Load DLL

IF (HLibrary> 31) // Load success

{

LPFUNC = GetProcaddress (Hlibrary, "Portin");

// Check the portin function address

IF (lpfunc! = (farproc) NULL)

// Call success

PortValue = (* lpfunc) (port); // read the value of the Port port

Freelibrary (HLibrary);

/ / Release the memory

}

Third, DLL application instance source program

1. Direct memory access DLL source code

//.Def file

Library

Memorydll

Description 'DLL for Memory_read_Write'

EXTYPE WINDOWS

Code

Preload Moveable Discardable

Data Prelioad Moveable Single

Heapsize 1024

// DLL does not have its own stack, so there is no STACKSIZE statement

Exports WEP @ 1 ResidentName

Readmemory

@2

WriteMemory @ 3

//.Cpp file

#include

Int Far Pascal Libmain (Hinstance Hinstance, Word Word Word WHEAPSIZE, LPSTR LPSZCMDLINE)

{

IF (WHEAPSIZE! = 0)

UNLOCKDATA (0);

Return

1;

}

INT FAR PASCAL MEMORYREAD (unsigned int dosoffset)

{

Word WDataSelector, Wselector;

Char far * pdata; char value;

WDASELECTOR = HiWord (Word Far *) & WDASELECTOR);

Wselector = allocselector (WDASELector);

// Assign selector

SetSelectorLimit (WSELECTOR, 0X2000);

// Save the boundary

SetSelectorBase (WSELECTOR, ((DWORD) Dosseg << 4) (DWORD) DOSOFFSET;

// 基 site

PDATA = (CHAR FAR *) (DWORD) WSELECTOR << 16);

Value = * pdata;

Freeselector (WSELECTOR);

// Release selector

Return (Value);

}

Void Far Pascal MemoryWrite (unsigned int dosoffset, char data)

{

Word WDataSelector, Wselector;

Char far * pdata;

WDASELECTOR = HiWord (Word Far *) & WDASELECTOR);

Wselector = allocselector (WDASELector);

SetSelectorLimit (WSELECTOR, 0X2000);

SetSelectorBase (WSELECTOR, ((DWORD) Dosseg << 4) (DWORD) DOSOFFSET;

PDATA = (CHAR FAR *) (DWORD) WSELECTOR << 16);

* pdata = data;

Freeselector (WSELECTOR);

}

INT FAR PASCAL WEP (INT NPARAM)

{

Return 1;

}

2. DLL source code reading and writing I / O

//.Def file

Library portdll

Description 'DLL for

Port_IN_OUT '

EXTYPE WINDOWS

Code Preload Moveable Discardable

Data

Preload Moveable Single

Heapsize 1024

//.Cpp file

#include

#include

Int Far Pascal

Libmain (Hinstance Hinstance, Word Word Word WHEAPSIZE, LPSTR LPSZCMDLINE)

{

IF (WHEAPSIZE! = 0)

UNLOCKDATA (0);

Return

1;

}

Int Far Pascal_export Portout (Int Port, Unsigned Char Value)

{

OUTP (Port, Value);

Return 1;

}

INT FAR PASCAL _EXPORT Portin (Int port)

{

Int result;

Result = INP (port);

Return (Result);

}

INT FAR PASCAL_EXPORT WEP (INT NPARAM)

{

Return 1;

}

The above two instances of the .def file and .cpp file each make up a .prj file, and compile the link into a .exe or .dll file, you can call it in the application.

Fourth, conclude

On the top, we use DLL technology to facilitate access to direct access and port I / O access to memory in the Windows environment, and the DLLs that are suitable for your application system, such as Port operations for data acquisition cards and extended memory area access, video zone buffers, and BIOS data area operations are in programming tasks. If necessary, just update the DLL directly, and use not to make any changes to the application itself, you can make a big improvement in the application's function and user interface, and implement the version upgrade. Therefore, mastering DLL technology is very beneficial to Windows program developers. - Author: saulia March 15, 2005, Tuesday 14:00 Reply (0) | Trackbacks (0). Add CASINO.

WINDOW message Daquan use details

The message means a notification issued by Windows to tell the application a matter. For example, click the mouse, change the window size, press a key on the keyboard to send Windows to your application. The message itself is passed to the application as a record, and this record contains the type of message and other information. For example, for messages generated by clicking on the mouse, this record contains the coordinates when clicking the mouse. This record type is called TMSG, which is declared in the Windows unit: typeTMSG = Packed RecordhWnd: hwnd; / / window handle Message: uint; / / message constant identifier WPARAM: WPARAM; // 32-bit message specific additional information LPARAM: LPARAM; / / 32-bit message Specific additional information Time: DWORD; / / message creation time PT: tpoint; / / message creation mouse position END; what is there? Do you feel that the information in a message record is like Greek? If this is the case, then take a look at the explanation below: HWND 32-bit window handle. The window can be any type of screen object because Win32 is able to maintain the handle of most visual objects (windows, dialogs, buttons, edit boxes, etc.). Message is used to distinguish constant values ​​for other messages, which may be predefined in the Windows unit, or they can be custom constants. WPARAM is usually a constant value related to messages or a handle of a window or control. LPARAM is usually a pointer to data in memory. Since W p A r a m, L P A R A M and P O i N t E r are 3 2 bits, so they can be converted between them.

WM_NULL = 0000; WM_CREATE = $ 0001; application creates a window WM_DESTROY = $ 0002; one window is destroyed WM_MOVE = $ 0003; moving a window WM_SIZE = $ 0005; change a window of the size WM_ACTIVATE = $ 0006; one window is activated or lost activation state; WM_SETFOCUS = $ 0007; WM_KILLFOCUS = $ 0008 after getting focus; lost focus WM_ENABLE = $ 000A; change Enable Status WM_SETREDRAW = $ 000B; Settings Window can redraw WM_SETTEXT = $ 000c; the application sends this message to set the text WM_Gettext = $ 000d; application sends this message to copy the text to the buffer wm_gettextLength = $ 000E for the corresponding window; get the length of the text related to a window (not including empty characters) WM_Paint = $ 000F; ask one window to call yourself WM_CLOSE = $ 0010; send a signal WM_QUERYENDSESSION = $ 0011 when a window or application is to be turned off; when the user selects the end dialog or the program you call the exitwindows function wm_quit = $ 0012; used to end the program to run or when the program calls PostquitMessage function wm_quitMessage function wm_quitMessage function WM_QUERYOPEN = $ 0013; When the user window restores the previous size position, send this message to an icon WM_ERASEBKGND = $ 0014; when the window background must be erased (case change the size of the window) WM_SYSCOLORCHANGE = 0015; send this message when the system color changes, send this message Give all top windows WM_ENDSESSION = $ 0016; After the system process issues a WM_QueryEndSession message, this message is sent to the application, informs it to end WM_SYSTEMERROR = $ 0017; WM_SHOWINDOW = 0018; when the hidden or display window is sent to this message to this message to this message to this message WM_ACTIVATEAPP = $ 001c; Send this message which window is activated, which is non-activated; WM_FONTCHANGE = 001D; send this message when the system's font resource library changes to all top windows WM_TIMECHANGE = $ 001E; when the system is time variation Send this message to all top windows WM_CANCELMODE = $ 001F; send this message to cancel Some ongoing touch state (operation) WM_SETCURSOR = $ 0020; if the mouse causes the cursor to move in a window and the mouse input is not captured, send a message to a window WM_MouseActivate = $ 0021; when the cursor is in a non-activated In the window, the user is in pressing a key in the mouse to send this message to the current window wm_childactivate = 0022; send this message to the MDI sub-window When the user clicks on this window, or when the window is activated, change, change the size WM_QUEESYNC = $ 0023; This message is sent by the computer-based training program, separating the user input message wm_getminMaxInfo = $ 0024 via the WH_Journalpalyback hook program; this message is sent to the window When it will change the size or position; WM_PaintICON = $ 0026; send it to the minimum window when it The icon will be saved WM_ICONERASEBKGND = $ 0027; this message is sent to a minimization window, only when it is drawing the icon, its background must be retransmond WM_NEXTDLGCTL = $ 0028;

Send this message to a dialog program to change the focus position wm_spoolerstatus = $ 002a; whenever the print management column is added or decreases this message WM_DRAWITEM = 002B; when Button, ComboBox, Listbox, Menu's visual appearance change Send this message to the owner of these empty pieces WM_MeasureItem = $ 002c; when Button, Combo Box, List Box, List View Control, or Menu Item is created, send this message to the control owner WM_DELETEITETEM = $ 002D; when the list box or combo box is destroyed or when certain items are deleted by LB_DELETESTRING, LB_RESETCONTENT, CB_DELETESTRING, or CB_RESETCONTENT news WM_VKEYTOITEM = $ 002E; this message is sent to a LBS_WANTKEYBOARDINPUT style of its owner in response to WM_KEYDOWN message WM_CHARTOITEM = $ 002F; This message is sent to his owner by a list box of LBS_WANTKEYBOARDINPUT to respond to WM_CHAR messages WM_SETFONT = $ 0030; when the text is drawn, the program sends this message to get the color wm_getfont = $ 0031 you want to use; the application sends this message to get the current control drawing Text fonts WM_SETHOTKEY = $ 0032; Application Send this message allows a window to associate with a hotkey WM_GETHOTKEY = $ 0033; the application sends this message to determine if the hotkey is related to the associated WM_QueryDragicon = $ 0037; this message is sent to the smallest The window, when this window will be dragged and dropped, it is not defined in its class, the application can return an icon or cursor handle, when the user drags and drop icon, the system displays this icon or cursor WM_CompareItem = $ 0039; send this message Determination of the relative position of ComboBox or ListBox added WM_GETOBJECT = $ 003d; WM_Compacting = $ 0041; Show memory has rarely wm_windowposchanging = $ 0046; send this message to the size and location of the window to call the SetWindowPos function or Other window management functions WM_WINDOWPOSCHANGE D = $ 0047; Send this message to the size and location of the window have been changed, call the SETWINDOWPOS function or other window management function wm_power = $ 0048; (for 16-bit Windows) When the system will send this message when the system will enter the pause WM_copyData = 004A; send this message when an application is delivered to another application WM_CANCELJournall = $ 004B; when a user cancels the program log activation status, submit this message to the program WM_NOTIFY = $ 004E; when a control When an event has occurred or this control needs to get some information, send this message to its parent window WM_INPUTLANGCHANGEREQUEST = $ 0050; when the user selects a kind of input language, or the hotkey of the language changes WM_INPUTLANGCHANGE = $ 0051; when the platform is already After changing this message to the affected top window wm_tcard = $ 0052; send this message when the program has initialized the Windows Help routine, send this message to the application WM_HELP = $ 0053; This message shows that the user presses F1, if a menu is activated Just send this message, this message is associated with the menu, otherwise send a window with focus, if there is no focus,

Send this message to the currently activated window WM_USERCHANGED = $ 0054; send this message to all windows when the user has already logged in or exits, when the user logs in or exits, the system updates the user's specific setup information, when the user update, the system is immediately Send this message; WM_NOTIFORMAT = 0055; public control, custom control, and their parent window to determine that the control is using ansi or a Unicode structure in the WM_NOTIFY message, using this control to make a control and its parent control Performing mutual communication WM_CONTEXTMENU = $ 007b; send this message to this message to this message when the user has a window, send this message to this message to change this message to that message when the calling setWindowlong function will change the style of one or more windows. WM_StyleChanged = 007d; send this message to that message to the window wm_displaychange = $ 007e after calling the setWindowlong function one or more windows; send this message to all windows WM_GETICON = $ 007f after the resolution change changes; this message is sent Give a window to return to a big icon or small icon for a window; wm_seticon = $ 0080; program sends this message to let a new big icon or small icon associate with a window; WM_NCCREATE = 0081; When the window is first created, this message is sent before the WM_CREATE message is sent; WM_NCDESTROY = $ 0082; This message notifies a window, the non-client area is destroying WM_NCCALCSIZE = $ 0083; when a window's customer area must be asked This message wm_nchittest = 0084; // Move the mouse, press and hold or release the mouse when it occurs when the program sends this message to a window When it (window) frame must be drawn; wm_ncactivate = 0086; this message is sent Some windows are only changed when its non-customer district needs to be changed. WM_GETDLGCODE = $ 0087; send this message to a control associated with the dialog program, Widdows control orientation keys and TAB keys make input into enter This control responds to the WM_GETDLGCODE message, the application can treat him as a special input control and can handle it WM_NCMOUSEMOVE = $ 00A0; when the cursor is moving this message to this message to this message to this message // Non-client To: the title bar of the form and the side frame of the window Wm_nclbuttondown = $ 00A1; Submit this message when the cursor is pressed at the non-customer area of ​​a window to submit this message WM_nclButtonUp = $ 00A2; when the user releases the left mouse button, the cursor is sent to the non-client zone ten; wm_nclbuttondblClk = $ 00A3; When the user double-click the left mouse button, the cursor is sent to the non-client zone 10. WM_NCRBUTTONDOWN = $ 00A4; when the user presses the mouse button, the cursor is sent to the window's non-client district when the cursor is sent to the window WM_ncrbuttonup = $ 00 A5; When the user releases the mouse button while sending this message when the cursor is in the non-client district of the window, the message is sent this message WM_ncrButtonDBLCLK = $ 00A6; when the user doubles the mouse button, the cursor is sent in the non-client zone 10 Send this message wm_ncmbuttondown = $ 00A7; when the user Press the mouse button and send this message when the cursor is in the non-client district of the window. WM_NCMBUTTONUP = $ 00A8; when the user releases the mouse button while the cursor is sent to the window of the window WM_NCMBUTTONDBLCLK = $ 00A9; when the user doubles The mouse button also sends this message when the cursor is in the non-client district of the window WM_KEYFIRST = $ 0100; WM_KEYDOWN =

$ 0100; // Press a key WM_KEYUP = $ 0101; // Release a key WM_CHAR = $ 0102; // Press a key and have issued WM_KEYDOWN, WM_KEYD IN, WM_KEYUP message WM_DEADCHAR = $ 0103; send this message when translating the WM_KEYUP message with TranslateMee Give the window wm_syskeydown = $ 0104; when the user pressed the Alt button, submit this message to the window with the focus; wm_syskeyup = $ 0105; when the user releases a button while the Alt key is submitted to submit this message with the focus window WM_SYSCHAR = $ 0106; submitted when WM_SYSKEYDOWN message after being TRANSLATEMESSAGE function to translate the message to the window WM_SYSDEADCHAR has focus = $ 0107; when WM_SYSKEYDOWN message after being TRANSLATEMESSAGE function translated sends this message to the window with the focus WM_KEYLAST = $ 0108; WM_INITDIALOG = $ 0110; Send this message before a dialog program is displayed to it, usually use this message to initialize the control and perform other tasks WM_COMMAND = $ 0111; when the user selects a menu command item or when a control sends a message to the parent window A shortcut is translated wm_syscommand = $ 0112; when a user selects a command to the window menu or when the user selects maximizes or minimizes the message, the message will receive this message WM_TIMER = $ 0113; // The timer event WM_HSCROLL = $ 0114; When a window standard horizontal scroll bar generates a scroll event to send this message to that window, also sent to the control WM_VSCROLL = $ 0115 with it; when a window standard vertical scroll bar generates a scroll event to send this message to that window, Send it to the control WM_INITMENU = $ 0116; when a menu is to be activated, it occurs in a user menu bar or pressing a menu button, which allows the program to change the menu WM_INITMENUPOPUPUP = $ 0117 This message will be sent when a drop-down menu or submenu will be activated, which allows the program to change the menu before it is displayed, not to change all WM_MENUSELECT = $ 011f; send this message to the menu when the user selects a menu item (Generally the window) WM_MenuChar = $ 0120; When the menu has been activated by the user (different from the accelerator), send this message to the menu Owner; wm_enterder = $ 0121; send this message to the owner of this message when a modal dialog or menu enters an on-load state, a modal dialog or menu enters an air-load status is to process one or more previous after the message is not a message of its queue waiting WM_MENURBUTTONUP = $ 0122; WM_MENUDRAG = $ 0123; WM_MENUGETOBJECT = $ 0124; WM_UNINITMENUPOPUP = $ 0125; WM_MENUCOMMAND = $ 0126; WM_CHANGEUISTATE = $ 0127; WM_UPDATEUISTATE = $ 0128; WM_QUERYUISTATE = $ 0129; WM_CTLCOLORMSGBOX = $ 0132; draw message box windows Before sending this message to the owner window of the message box, by responding to this message, the owner window can set the text and background color wm_ctlcoloredit = $ 0133; when an editing control is used by using the handle of the given related display device; This message will be sent to the parent window to send this message; by responding to this message,

Owner window You can set the edit box for text and background color wm_ctlcolorlistbox = $ 0134 by using a given relevant display device; when a list box control will be drawn before you send this message to its parent window; respond to this message The owner window can set the list box for text and background color wm_ctlcolorbtn = $ 0135 by using a given relevant display device; when a button control will be drawn, send this message to the parent window; by responding to this message The owner window can set the text and background color wm_ctlcolordlg = $ 0136 by using a given relevant display device; when a dialog control will be drawn before sending this message to the parent window; by response to this Message, the owner window can set the text background color WM_CTLCOLORSCROLLBAR = $ 0137 by using a given related display device; when a scroll bar control will be drawn, send this message to its parent window; by response to this Message, the owner window can set the background color WM_CTLCOLORSTATIC = $ 0138 of the scroll bar by using the handle of a given related display device; when a static control will be drawn to the parent window; by responding to this message, The owner window can set the text and background color wm_mousefirst = $ 0200; WM_MouseMove = $ 0200; // mobile mouse wm_lbuttondown = $ 0201; // Press the left mouse button WM_LButtonup = $ 0202; // release the left mouse button WM_LBUTTONDBLCLK = $ 0203; // double-click the left mouse button WM_RBUTTONDOWN = $ 0204; // press the right mouse button WM_RBUTTONUP = $ 0205; // release the right mouse button WM_RBUTTONDBLCLK = $ 0206; // Double-click the right mouse button WM_MBUTTONDOWN = $ 0207; // Press the mouse button WM_MBUTTONUP = $ 0208; // Release the mouse button WM_MBUTTONDBLCLK = $ 0209; // Double click on the mouse button WM_MouseWheel = $ 020A; send this message when the mouse wheel rotates WM_MouseLast = $ 020A; WM_ParentNotify = $ 0210; When the MDI sub-window is created or destroyed, or the user presses the mouse button and the cursor will send this message to the parent window WM_Enterm Enuloop = $ 0211; Send this message to notify the application's main window That already entered the menu loop mode WM_EXITMENULOOP = $ 0212; send this message to notify the application's main window That has exited menu loop mode WM_NEXTMENU = $ 0213; wm_sizing = 532; This message is being adjusted to the window; you can monitor the window size and position can also modify the window size and location. You can also modify them WM_CAPTURECHANGED = 533; send this message to the window When it lost the captured mouse; WM_MOVING = 534; when the user is This message will be sent when the window is sent, and you can monitor the window size and location. You can also modify them; WM_PowerBroadcast = 536; this message is sent to the application to notify it about power management events; WM_DEviceChange = 537; when the device is hardware configuration Send this message to the application or device driver WM_IME_STARTCOMPSITION = $ 010D; WM_IME_Composition = $ 010F; WM_IME_KEYLAST = $ 010F;

WM_IME_SETCONTEXT = $ 0281; WM_IME_NOTIFY = $ 0282; WM_IME_CONTROL = $ 0283; WM_IME_COMPOSITIONFULL = $ 0284; WM_IME_SELECT = $ 0285; WM_IME_CHAR = $ 0286; WM_IME_REQUEST = $ 0288; WM_IME_KEYDOWN = $ 0290; WM_IME_KEYUP = $ 0291; WM_MDICREATE = $ 0220; application sends this message to the customer and more documents Window to create an MDI sub-window WM_MDIDESTROY = $ 0221; the application sends this message to the multi-document client window to close a MDI sub-window WM_MDIACTIAACTIAFATE = $ 0222; application sends this message to the multi-document client window to inform the customer window to activate another MDI Sub window, when the customer window receives this message, it issues a WM_MDIACTIVE message to the MDI sub-window (not activated) to activate it; WM_MDIRESTORE = $ 0223; program sends this message to the MDI customer window allows sub-windows from the maximum minimum minimization to the original size WM_MDINEXT = $ 0224; Program Send this message to the MDI Customer window to activate the next or the previous window WM_MDIMAXIMIZE = $ 0225; the program sends this message to maximize a MDI sub-window; wm_mditile = $ 0226; program sends this message to MDI customers The window rearranges all MDI sub-window WM_MDICASCADE = $ 0227; program sends this message to the MDI client window to rearrange all MDI sub-window WM_MDIICONARRANGE = $ 0228; program sends this message to the MDI customer window rearrange all minimization MDI child windows WM_MDIGETACTIVE = $ 0229; program sends the message to the MDI client window to find the handle WM_MDISETMENU activated sub-window = $ 0230; sends this message to the MDI client window instead of the menu WM_ENTERSIZEMOVE child window by MDI menu = $ 0231; WM_EXITSIZEMOVE = $ 0232 WM_DROPFILES = $ 0233; wm_mdirefreshmenu = $ 0234; wm_mousehover = $ 02A1; wm_mouseeleave = $ 02A3; WM_CUT = $ 0300; program sends this elimination Interest to an edit box or ComboBox to delete the currently selected text wm_copy = $ 0301; program sends this message to a edit box or ComboBox to copy the currently selected text to the clipboard WM_PASTE = $ 0302; the program sends this message to EditControl or ComboBox from the clip plates obtained data WM_CLEAR = $ 0303; program sends the message to editcontrol or combobox clear the currently selected content; WM_UNDO = $ 0304; program sends the message to editcontrol or combobox undo the last operation WM_RENDERFORMAT = $ 0305; WM_RENDERALLFORMATS = $ 0306; WM_DESTROYCLIPBOARD = $ 0307; When the EnpTyClipboard function is sent to the owner of the clipboard to the owner of the clipboard, WM_DRAWCLIPBOARD = $ 0308; send this message to the first window of the clipboard to observe the chain when the content changes of the clipboard; it allows the window to display the clipboard New content; WM_PaintClipboard = $ 0309; when the clipboard contains data in the CF_OWNERDIPLAY format and the clipboard observation window needs to be heavy; WM_VScrollClipboard = $ 030A;

WM_SIZECLIPBOARD = $ 030B; When the clipboard contains data in the CF_OWNERDIPLAY format and the size of the clipboard observation window has changed this message, the message is sent to the owner of the clipboard by the clipboard observation window; WM_ASKCBFORMATNAME = $ 030c; observation by clipboard The window sends this message to the owner of the clipboard to request a clipboard of a CF_OWNERDISPLAY format WM_CHANGECBCHAIN ​​= $ 030D; when a window is removed from the clipboard observed chain, send this message to the first window of the clipboard observation chain. WM_HSCROLLLPBOARD = $ 030E; This message sends the owner of the clipboard through a clipboard watch window; it occurs in the clipboard contains data in the CFOWNERDISPALY format and has an event on the horizontal scroll bar of the clipboard viewing window; owner The clipboard image should be scrolled and update the value of the scroll bar; WM_QUERYNEWPALETTE = $ 030F; this message is sent to the window to receive the focus, this message enables the window to have the opportunity to achieve his logical palette WM_PALETTEISCHANGING when receiving the focus = $ 0310; When an application is to implement its logical palette, you send this message to notify all applications WM_PALETTECHANGED = $ 0311; this message is sent to all the logical palette after a focus window, send this message to all Top-level and overlapping windows to change the system palette WM_HOTKEY = $ 0312; submit this message when the user presses the hotkey registered by the RegisterhotKey function; the application sends this message only when Windows or other applications are issued a request requires drawing a portion of an application; WM_PRINTCLIENT = 792; WM_HANDHELDFIRST = 856; WM_HANDHELDLAST = 863; WM_PENWINFIRST = $ 0380; WM_PENWINLAST = $ 038F; WM_COALESCE_FIRST = $ 0390; WM_COALESCE_LAST = $ 039F; WM_DDE_FIRST = $ 03E0; WM_DDE_INITIATE = WM_DDE_FIRST 0 A DDE client submits this message to start a session of the server to respond to the specified program and theme name; WM_DDE_TERMINATE = WM_DDE_FIRST 1; a DDE application (whether a customer or server) submit this message Terminate a session; WM_DDE_ADVISE = WM_DDE_First 2; a DDE client submits this message to a DDE service program to request the server whenever the data item changes it when the data item changes it WM_DDE_UNADVISE = WM_DDE_First 3; a DDE client invides a DDE service does not update the specified item or a special clipboard format entry WM_DDE_ACK = WM_DDE_FIRST 4; this message informs a DDE (dynamic data exchange) program has been received and is being processed WM_DDE_POKE, WM_DDE_EXECUTE, WM_DDE_DATA, WM_DDE_ADVISE, WM_DDE_UNADVISE, or WM_DDE_INITIAT Message WM_DDE_DATA = WM_DDE_FIRST 5; a DDE service program submits this message to the DDE client to deliver a data item to a customer or notifying a customer's available data item WM_DDE_REQUEST = WM_DDE_FIRST 6; a DDE client submits this message to a DDE The service program requests the value of a data item; WM_DDE_POKE = WM_DDE_FIRST 7;

转载请注明原文地址:https://www.9cbs.com/read-132234.html

New Post(0)