Is there an assembly version of wsprint?
wprintf(L"GetMessageResources failed.\n");
; wprintf is a wide-character version of printf; format is a wide-character string.
; wprintf and printf behave identically if the stream is opened in ANSI mode.
; printf does not currently support output into a UNICODE stream.
I found some wprintf statements in msvcrt.inc.
Hi Magnum,
Here is an example for you :
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\msvcrt.inc
include \masm32\macros\ucmacros.asm
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\msvcrt.lib
.data
WSTR str1,"Simple calculation"
WSTR format1,"%s : 7 + 3 = %d"
.data?
.code
start:
invoke crt_wprintf,ADDR format1,ADDR str1,10
invoke ExitProcess,0
END start
At least for the Microsoft CRT, you don't need to use the wide-character version of printf to display Unicode strings, you just need to use the right type character in the format string.
;====================================================================
include \masm32\include\masm32rt.inc
include \masm32\macros\ucmacros.asm
;====================================================================
.data
WSTR buffer,"my other brother darryl"
.code
;====================================================================
start:
;====================================================================
invoke crt_printf, cfm$("%s\n%S\n"), ADDR buffer, ADDR buffer
inkey "Press any key to exit..."
exit
;====================================================================
end start
m
my other brother darryl
http://msdn.microsoft.com/en-us/library/hf4y5e3w(VS.71).aspx
invoke crt_printf, chr$("%S"), wChr$("TheString")
; %S: When used with printf functions, specifies a wide-character string
That works perfectly. But I cannot convince printf to produce output with a real Unicode example, i.e. Russian or Chinese text that otherwise displays fine in a wide message box... which, by the way, is a mystery that has been treated already in the WriteConsoleW thread (http://www.masm32.com/board/index.php?topic=13696.0), unsuccessfully.
It works with strings returned by the API:
;====================================================================
include \masm32\include\masm32rt.inc
include \masm32\macros\ucmacros.asm
;====================================================================
.data
buffer db 1024 dup(0)
.code
;====================================================================
start:
;====================================================================
invoke GetCurrentDirectoryW, 512, ADDR buffer
invoke crt_printf, cfm$("%S\n"), ADDR buffer
inkey "Press any key to exit..."
exit
;====================================================================
end start
Jochen - i think, in a console window, you have to select a code page
try the dos CHCP command
there is a way to do it in the environment table, too - if you want it to be permanent
Quote from: dedndave on January 30, 2011, 03:38:08 PM
Jochen - i think, in a console window, you have to select a code page
try the dos CHCP command
there is a way to do it in the environment table, too - if you want it to be permanent
Dave, I have tested dozens already... crt_printf just prints an empty string for anything that is not plain abc. Win XP consoles don't like Russian, Chinese and other exotic characters.
invoke crt_printf, chr$("%S"), wChr$("TheString", 13, 10) ; %S: When used with printf functions, specifies a wide-character string
wLet esi=wRes$(001) ; "Enter text here"
invoke crt_printf, chr$("%S%S"), esi, wChr$(" - OK?", 13, 10)
invoke SetConsoleOutputCP, 50000 ; 50000 associated with Lucida Console
invoke crt_printf, chr$("%S%S"), esi, wChr$(" - OK?", 13, 10)
wLet esi=wRes$(401) ; "Enter text here" in Russian
invoke crt_printf, chr$("%S%S"), esi, wChr$(" - OK?", 13, 10)
wLet esi=wRes$(801) ; "Enter text here" in Chinese
invoke crt_printf, chr$("%S%S"), esi, wChr$(" - OK?", 13, 10)
wLet esi=wRes$(1201)
invoke crt_printf, chr$("%S%S"), esi, wChr$(" - OK?", 13, 10)
TheString
Enter text here - OK?
Enter text here - OK?
- OK?
- OK?
- OK?
ok, Jochen....
name one language you would like to see (Chinese, Arabic - whatever)
give me a console-mode program that should display text in that language
i will see if i can make it work :U
keep in mind that i do not read Chinese or Arabic - lol
Russian would be a good choice, as we have a few Russian members
i don't read Russian, either :P
wprintf(L"GetMessageResources failed.\n");
I can't see that I need wprintf just to print a text string.
Is there something that I don't understand ?
In the code sections there are a lot of goto statements.
Isn't that inefficient?
Maybe that why C code is often times bloated. :U
well - that's a good assessment - lol
but - they grab wprintf because the function is in msvcrt, which already exists on all computers
there is something to be said for that, too
the msvcrt functions are, for the most part, flexible, fast and reliable
Computers in general or those with a Windows O.S. ?
sorry about that
essentially all windows OS computers have msvcrt of some form or another on them
Quote from: dedndave on January 30, 2011, 05:51:22 PM
ok, Jochen....
name one language you would like to see (Chinese, Arabic - whatever)
Dave,
QuoteEnter text here
Click on this button
Welcome
Введите текст здесь
Нажмите на эту кнопку
Добро пожаловать
أدخل النص هنا
دفع هذا الزر
مرحبا بكم
在這裡輸入文字
按一下這個按鈕
歡迎
... seeing the text in a console is not really the problem. What bogs me down is that under certain, hardly predictable circumstances it works, under others not. Certain is that the user must set Lucida Console under console properties. Uncertain is why it works when I assemble & link & run it from RichMasm or when I run it from a DOS prompt, but not from Explorer or from Start Run...
Here is the full code, using a resource string table with IDs 1-3, 401-403, 801-803, 1201-1203 for the respective languages:
Quote MyCP=CP_UTF8
invoke SetConsoleOutputCP, MyCP ; CP_UTF8 aka 65001 WORKS...!!
ConsoleColor cWhite, cBlue ; normal CP is 1252 for Western text; user must set console properties to Lucida Console
For_ Lang=0 To 3
imul edi, Lang, 400
For_ n=1 To 3
wLet esi=wRes$(n+edi)+wCrLf$ ; get a Unicode string from the resource stringtable
push ecx
invoke WideCharToMultiByte, MyCP, 0, esi, -1, 0, 0, NULL, NULL ; 0, 0: get buffer size
inc eax
push eax
Let ebx=New$(eax) ; create a buffer for the multibyte string
pop eax
invoke WideCharToMultiByte, MyCP, 0, esi, -1, ebx, eax, NULL, NULL
pop ecx
Print ebx
Next
Print
Next
I would like to enter some Korean text and send in via email.
I am working on this now.
Am I on the right track?
; DWORD GetLastRecordNumber(HANDLE hEventLog, DWORD* pdwMarker);
;
; BOOL GetOldestEventLogRecord(
;
; HANDLE hEventLog, // handle to event log
; PDWORD OldestRecord // buffer for number of oldest record
; );
GetLastRecordNumber PROC hFile:DWORD,
invoke GetOldestEventLogRecord, hFile,
ret
GetLastRecordNumber endp
Hi,
QuoteUncertain is why it works when I assemble & link & run it from RichMasm or when I run it from a DOS prompt, but not from Explorer or from Start Run...
Not sure if this is relevant, but in reading a newsgroup, a
thread was discussing something similar. The environment
was inherited from the command processor when started
from the command line. But when started with a START
command, or some other ways, the environment, including
file handles, were different. So querying the environments
might show what is different?
Regards,
Steve
Quote from: Magnum on January 30, 2011, 10:02:09 PM
I would like to enter some Korean text and send in via email.
Korean doesn't work on my system. Chinese, Thai, Japanese yes, Korean no...
Quote from: jj2007 on January 30, 2011, 04:05:17 PM
Quote from: dedndave on January 30, 2011, 03:38:08 PM
Jochen - i think, in a console window, you have to select a code page
try the dos CHCP command
there is a way to do it in the environment table, too - if you want it to be permanent
Dave, I have tested dozens already... crt_printf just prints an empty string for anything that is not plain abc. Win XP consoles don't like Russian, Chinese and other exotic characters.
MSVCRT converts Unicode text to ASCII before output to console for simpler and unified console/file output.
Try to do:
invoke crt__setmbcp,CodePage
before output.
Still, this will limit output by one extended ASCII language.
For Russian, CodePage is: 1251
Quote from: Antariy on January 30, 2011, 11:41:29 PM
For Russian, CodePage is: 1251
Alex,
Russian prints fine with CodePage CP_UTF8 (65001). The other languages behave a bit erratically, although they do work from the
cmd DOS prompt.
Quote from: jj2007 on January 30, 2011, 11:54:15 PM
Quote from: Antariy on January 30, 2011, 11:41:29 PM
For Russian, CodePage is: 1251
Alex,
Russian prints fine with CodePage CP_UTF8 (65001). The other languages behave a bit erratically, although they do work from the cmd DOS prompt.
How about UTF7 (65000) ? That's joke :lol
Quote from: Antariy on January 30, 2011, 11:59:47 PM
How about UTF7 (65000) ? That's joke :lol
Why joke? It works, actually, likewise 1200 and 1201. This is because a true Unicode (2-byte) strings gets translated to a "multibyte" string that WriteConsoleA can interpret.
Other codepages work partially, for Russian only.
The source is included in reply #12 (you have the MB package, I suppose).
I'm no expert in this area, but don't you have to set the correct CodePage and the correct font for the language you want to display. They will be different for each language.
Some relevant links:
Keep your eye on the code page (http://blogs.msdn.com/b/oldnewthing/archive/2005/03/08/389527.aspx)
Why are console windows limited to Lucida Console and raster fonts? (http://blogs.msdn.com/b/oldnewthing/archive/2007/05/16/2659903.aspx)
Consolas can also be used for the console font. It first came with Windows Vista.
Quote from: jj2007 on January 31, 2011, 07:49:57 AM
Quote from: Antariy on January 30, 2011, 11:59:47 PM
How about UTF7 (65000) ? That's joke :lol
Why joke? It works, actually, likewise 1200 and 1201. This is because a true Unicode (2-byte) strings gets translated to a "multibyte" string that WriteConsoleA can interpret.
Other codepages work partially, for Russian only.
The source is included in reply #12 (you have the MB package, I suppose).
Actually "codepages" 1200 and 1201 does not exist. This is just "shortcut name", but you'll not find codapage file with encoding table for these sets. The same as UTF8 - it is just conversion from Unicode UTF-16 (UCS2) (there is some simple rules).
Quote from: jj2007 on January 30, 2011, 09:57:35 PMUncertain is why it works when I assemble & link & run it from RichMasm or when I run it from a DOS prompt, but not from Explorer or from Start Run...
This problem vexes me... I wish i could reproduce the problem, but am having no luck (now, or before in the previous thread). Whether running from the shell or cmd.exe, i get the same results every time (English, Russian?, Arabic, Boxes, using DejaVu sans Mono). I really think the weak link in the chain is the actual font that you use, and not the function, but as of now I have nothing to back it up. What is the copy/paste behavior? When I mark/copy and paste into notepad++ (with encoding set to UTF-8), i see all perfectly, and the boxes change to asian.
-r
Red,
Have you tried the Feb 1 build of MB? Test this snippet with the attached resource file...
I see Russian, Arabic and Chinese:
Test: Введите текст здесь
Test: أدخل النص هنا
Test: 在這裡輸入文字
Quoteinclude \masm32\MasmBasic\MasmBasic.inc
Init [/color]
wPrint wChr$("Test: "), wRes$(401), wCrLf$
wPrint wChr$("Test: "), wRes$(801), wCrLf$
wInkey wChr$("Test: "), wRes$(1201)
Exit
end start
(http://www.masm32.com/board/index.php?action=dlattach;topic=16000.0;id=8850)
the attachment is the above image
All 3 languages show up OK here. I keep the east asian fonts loaded.
Quoteimage.zip (1.79 KB - downloaded 17 times.)
:lol
Quote from: redskull on February 02, 2011, 02:38:03 AM
This problem vexes me...
Red,
To give you one more element: The first wPrint invokes SetConsoleOutputCP, CP_UTF8 (no surprise) and SetConsoleTextAttribute. Without the latter call, Russian displays fine but Arabic and Chinese don't...
@Dave & Hutch: Thanks for your feedback!
What do you mean by an Assembly equivalent?
I just invoke WSPrintF directly... only trick is to explicitly call the unicode version by appending W to it.
.586
.model flat, stdcall
option casemap :none
; To get unicode support
include \masm32\macros\ucmacros.asm
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
wsprintfW PROTO C :VARARG
.data
WSTR FormatString, "Some String with a number"
ptrFinalString dd 0
.code
main:
; Make space
invoke GetProcessHeap
invoke HeapAlloc, eax, HEAP_ZERO_MEMORY, 1024; 1024 is enough bytes I think for this example
mov ptrFinalString, eax
; Sprintf
invoke wsprintfW, ptrFinalString, ADDR FormatString, DWORD PTR [eax]
; Show result
invoke MessageBoxW, NULL, ptrFinalString, ptrFinalString, MB_OK
invoke ExitProcess, 0
end main
Thanks, your help is helping with my large project.
Andy