iczelion tut35[13]

[入库:2005年8月19日] [更新:2007年3月24日]

本文简介:选择自 jimgreen 的 blog

		invoke sendmessage,hwnd,em_getrect,0,addr rect
		invoke sendmessage,hwnd,em_charfrompos,0,addr rect
		invoke sendmessage,hwnd,em_linefromchar,eax,0
		invoke sendmessage,hwnd,em_lineindex,eax,0

we want to obtain the visible text so we first have to obtain the formatting rectangle by sending em_getrect message to the richedit control. now that we have the bounding rectangle, we obtain the nearest character index to the upper left corner of the rectangle with em_charfrompos. once we have the character index (the first visible character in the control), we can start to do syntax hilighting starting from that position. but the effect might not be as good as when we start from the first character of the line that the character is in. that's why i need to obtain the line number of that the first visible character is in by sending em_linefromchar message. to obtain the first character of that line, i send em_lineindex message.

		mov txtrange.chrg.cpmin,eax
		mov firstchar,eax
		invoke sendmessage,hwnd,em_charfrompos,0,addr rect.right
		mov txtrange.chrg.cpmax,eax

once we have the first character index, store it for future reference in firstchar variable. next we obtain the last visible character index by sending em_charfrompos, passing the lower-right corner of the formatting rectangle in lparam.

		push rect.left
		pop realrect.left
		push rect.top
		pop realrect.top
		push rect.right
		pop realrect.right
		push rect.bottom
		pop realrect.bottom
		invoke createrectrgn,realrect.left,realrect.top,realrect.right,realrect.bottom
		mov hrgn,eax
		invoke selectobject,hdc,hrgn
		mov holdrgn,eax

while doing syntax hilighting, i noticed an unsightly side-effect of this method: if the richedit control has a margin (you can specify margin by sending em_setmargins message to the richedit control), drawtext writes over the margin. thus i need to create a clipping region, the size of the formatting rectangle, by calling createrectrgn. the output of gdi functions will be clipped to the "writable" area.

next, we need to hilight the comments first and get them out of our way. my method is to search for ";" and hilight the text with the comment color until the carriage return is found. i will not analyze the routine here: it's fairly long and complicated. suffice here to say that, when all the comments are hilighted, we replace them with 0s in the buffer so that the words in the comments will not be processed/hilighted later.

		mov ecx,buffersize
		lea esi,buffer
		.while ecx>0
			mov al,byte ptr [esi]
			.if al==" " || al==0dh || al=="/" || al=="," || al=="|" || al=="+" || al=="-" || al=="*" || al=="&" || al=="<" || al==">" || al=="=" || al=="(" || al==")" || al=="{" || al=="}" || al=="[" || al=="]" || al=="^" || al==":" || al==9
				mov byte ptr [esi],0
			.endif
			dec ecx
			inc esi
		.endw

once the comments are out of our way, we separate the words in the buffer by replacing the "separator" characters with 0s. with this method, we need not concern about the separator characters while processing the words in the buffer anymore: there is only one separator character, null.

		lea esi,buffer
		mov ecx,buffersize
		.while ecx>0
			mov al,byte ptr [esi]
			.if al!=0

search the buffer for the first character that is not null,ie, the first character of a word.

				push ecx
				invoke lstrlen,esi
				push eax
				mov edx,eax

obtain the length of the word and put it in edx

				movzx eax,byte ptr [esi]
				.if al>="a" && al<="z"
					sub al,"a"
					add al,"a"
				.endif

convert the character to lowercase (if it's an uppercase character)

本文关键:iczelion asm
  相关方案
Google
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top