From tom@@@k@||ber@ @end|ng |rom gm@||@com  Wed May 11 18:32:23 2022
From: tom@@@k@||ber@ @end|ng |rom gm@||@com (Tomas Kalibera)
Date: Wed, 11 May 2022 18:32:23 +0200
Subject: [Rd] Rgui.exe 4.2.0 does not receive characters via the Windows
 API's PostMessage function
In-Reply-To: <82957f65-28f0-cc11-b07b-1e6076d23d9c@gmail.com>
References: <em26d64aef-2f66-415f-be9d-ae71a91c1d56@dell>
 <8e41c7bc-466c-ca00-6141-66520f8818b8@gmail.com>
 <em8cb2eaf6-27fe-4d26-84b2-3eef11fa9530@dell>
 <5e580ff4-ac60-6b79-e0d7-f9a84ee200d7@gmail.com>
 <em46f02f23-aa3d-4db3-9f88-1b338b047298@dell>
 <7bbdbe00-51e2-e9cf-ae16-5e969fb756b7@gmail.com>
 <82957f65-28f0-cc11-b07b-1e6076d23d9c@gmail.com>
Message-ID: <a8733d02-ff78-a41b-446c-7347268bb27f@gmail.com>


On 5/11/22 15:39, Tomas Kalibera wrote:
>
> On 5/11/22 08:15, Tomas Kalibera wrote:
>>
>> On 5/11/22 03:02, jcfaria wrote:
>>> Dear Tomas,
>>> I've tried, but I don't have the necessary C/C++ programming skills 
>>> to fulfill your request.
>>>
>>> Maybe someone can help us by transcribing the little code in object 
>>> Pascal that I sent to C/C++.
>>>
>>> If a small executable, made in Object Pascal, can help in your 
>>> debug, I can provide.
>>
>> Dear Jose,
>>
>> no problem, I can try out with the Pascal code.
>> Is there a free compiler I can use to build and run it?
>
> Actually I can reproduce it in a C program doing the same thing.
>
> The primary cause is that Rgui is using GraphApp Unicode windows on 
> systems running in a multi-byte locale, which affects most systems 
> since R 4.2 because of the switch to UTF-8. While Unicode windows have 
> been used even in older versions of R, it was only on systems then 
> running in a multi-byte locale, and apparently this hasn't been reported.
>
> When I modify R-devel to use non-Unicode GraphApp windows, the message 
> sending works again. I will have a closer look, thanks for the report.

I had a closer look and this doesn't really seem to be a bug in R to me. 
For Unicode Windows, GraphApp uses WM_IME_COMPOSITION messages to read 
the keys instead of WM_CHAR, which it uses for non-Unicode windows. This 
is internal functionality of Rgui and a legitimate choice. Rgui cannot 
simply handle both messages in Unicode windows, because the characters 
would be doubled (if you see an easy, elegant change to Rgui that would 
mimic the previous behavior, let me know). This is certainly not a 
documented interface for Rgui, so I am afraid you would have to change 
something in your application.

I read that using PostMessage to simulate keyboard input is considered 
wrong, see [1], and then one should instead use SendInput (which then 
requires bringing the window to the foreground), if at all simulating 
keyboard input. Maybe one could create a better working solution that 
way, or using some automation library.

As a quick hack, I found that [2] happens to be working on my system, 
but again relying on the current implementation of Rgui (simply you send 
WM_KEYDOWN also for the characters other than the newline/return). It 
seems to be working also with R 4.1 for me.

The usual way for GUIs/front-ends is to "embed" R, to link it as a DLL. 
Rgui itself does it and also external applications such as RStudio. 
Typically you would want to have a thin layer application embedding R 
and make your GUI communicate with that, but switching to that from 
sending the messages would require some work.

Best
Tomas

[1] https://devblogs.microsoft.com/oldnewthing/20050530-11/?p=35513

[2]
#include <windows.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
 ? HWND hw;
 ? int i, res;

 ? printf("Getting Rgui window...\n");
 ? hw = FindWindow(NULL, "R Console (64-bit)");

 ? printf("Got window: %x\n", hw);
 ? if (hw == NULL) {
 ??? printf("Could not get Rgui window: %x\n", GetLastError());
 ??? return 2;
 ? }

 ? char *sd = "sd";
 ? for(i = 0; i < strlen(sd); i++) {
 ??? res = PostMessage(hw, WM_KEYDOWN, VkKeyScan(sd[i]), 0);
 ??? printf("Sending char %c: %d.\n", sd[i], res);
 ? }

 ? res = PostMessage(hw, WM_KEYDOWN, VK_RETURN, 0);
 ? printf("Sending return: %d\n.", res);
 ? return 0;
}


>
> For reference, to reproduce I ran
>
> Rgui --sdi
>
> and used this C example:
>
> #include <windows.h>
> #include <stdio.h>
> #include <string.h>
>
> int main(int argc, char **argv) {
> ? HWND hw;
> ? int i, res;
>
> ? printf("Getting Rgui window...\n");
> ? hw = FindWindow(NULL, "R Console (64-bit)");
>
> ? printf("Got window: %x\n", hw);
> ? if (hw == NULL) {
> ??? printf("Could not get Rgui window: %x\n", GetLastError());
> ??? return 2;
> ? }
>
> ? char *sd = "sd";
> ? for(i = 0; i < strlen(sd); i++) {
> ??? res = PostMessage(hw, WM_CHAR, (unsigned int) sd[i], 0);
> ??? printf("Sending char %c: %d.\n", sd[i], res);
> ? }
>
> ? res = PostMessage(hw, WM_KEYDOWN, VK_RETURN, 0);
> ? printf("Sending return: %d\n.", res);
> ? return 0;
> }
>
> Best
> Tomas
>
>
>>
>> Thanks
>> Tomas
>>
>>>
>>> Grateful for the attention,,
>>> ///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\
>>> Jose Claudio Faria
>>> UESC/DCET/Brasil
>>> joseclaudio.faria at gmail.com
>>> Telefones:
>>> 55(73)3680.5545 - UESC
>>> 55(73)99966.9100 - VIVO
>>> ///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\
>>> If you have software to deal with statistics, you have arms,
>>> if you have good software, you have arms and legs,
>>> if you have software like R, you have arms, legs and wings...
>>> the height of your flight depends only on you.
>>>
>>> ------ Mensagem original ------
>>> De: "Tomas Kalibera" <tomas.kalibera at gmail.com>
>>> Para: "jcfaria" <joseclaudio.faria at gmail.com>; "Duncan Murdoch" 
>>> <murdoch.duncan at gmail.com>; r-devel at r-project.org
>>> Enviado(s): 06/05/2022 04:24:44
>>> Assunto: Re: [Rd] Rgui.exe 4.2.0 does not receive characters via the 
>>> Windows API's PostMessage function
>>>
>>>>
>>>> On 5/6/22 07:03, jcfaria wrote:
>>>>> Dear Duncan,
>>>>> I believe the problem is of a different nature.
>>>>> I get TRUE 3 times running the code below:
>>>>>
>>>>> procedure TfMain.btnPasteClick(Sender: TObject);
>>>>> var
>>>>> ? i: integer;
>>>>> ? sTmp: string;
>>>>> ? hBN: HWND;
>>>>> ? j: bool;
>>>>>
>>>>> begin
>>>>> ? hBN:= FindWindowA(nil,
>>>>> ??????????????????? 'R Console (64-bit)');
>>>>>
>>>>> ? sTmp:= 'sd';
>>>>>
>>>>> ? for i:= 1 to Length(sTmp) do begin
>>>>> ??? j:= PostMessage(hBN,
>>>>> ??????????????????? WM_CHAR,
>>>>> ??????????????????? Ord(sTmp[i]),
>>>>> ??????????????????? 0);
>>>>>
>>>>> ??? ShowMessage(BoolToStr(j,
>>>>> ????????????????????????? True));
>>>>> ? end;
>>>>>
>>>>> ? j:= PostMessage(hBN,
>>>>> ????????????? WM_KEYDOWN,
>>>>> ????????????? VK_RETURN, 0);
>>>>>
>>>>> ? ShowMessage(BoolToStr(j,
>>>>> ??????????????????????? True));
>>>>> end;
>>>>>
>>>>> That is, Rgui is receiving the message of the characters (via 
>>>>> PostMessage), but it is blocking because it does not show them in 
>>>>> the console.
>>>>> The only thing Rgui blames is Carriage Return, as it adds an 
>>>>> additional prompt with each run.
>>>>
>>>> I can't provide a good guess what impacted your use, but if you 
>>>> could give me a full example, ideally in C, which can be compiled 
>>>> with Rtools42 (so gcc, MinGW) and I can edit/recompile, and works 
>>>> with R 4.1, I am happy to help debugging on 4.2.
>>>>
>>>> Rgui now uses GraphApp Unicode windows on systems where it didn't 
>>>> before, because it uses UTF-8 also on systems it didn't before (on 
>>>> systems that would use a single-byte locale in R 4.1). These 
>>>> Unicode windows are a different code path and there may be bugs not 
>>>> reported previously, including processing inputs (recently I fixed 
>>>> handling of accents, for example). Otherwise indeed R now uses 
>>>> UTF-8 as native encoding and UCRT as the C runtime.
>>>>
>>>> Best
>>>> Tomas
>>>>
>>>>
>>>>>
>>>>> >
>>>>> >
>>>>>
>>>>> Best,
>>>>> ///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\
>>>>> Jose Claudio Faria
>>>>> UESC/DCET/Brasil
>>>>> joseclaudio.faria at gmail.com
>>>>> Telefones:
>>>>> 55(73)3680.5545 - UESC
>>>>> 55(73)99966.9100 - VIVO
>>>>> ///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\
>>>>> If you have software to deal with statistics, you have arms,
>>>>> if you have good software, you have arms and legs,
>>>>> if you have software like R, you have arms, legs and wings...
>>>>> the height of your flight depends only on you.
>>>>>
>>>>> ------ Mensagem original ------
>>>>> De: "Duncan Murdoch" <murdoch.duncan at gmail.com>
>>>>> Para: "jcfaria" <joseclaudio.faria at gmail.com>; r-devel at r-project.org
>>>>> Enviado(s): 05/05/2022 13:17:53
>>>>> Assunto: Re: [Rd] Rgui.exe 4.2.0 does not receive characters via 
>>>>> the Windows API's PostMessage function
>>>>>
>>>>>> On 05/05/2022 11:17 a.m., jcfaria wrote:
>>>>>>> Hello,
>>>>>>>
>>>>>>> Rgui.exe 4.2.0 does not receive characters via the Windows API's
>>>>>>> PostMessage function.
>>>>>>>
>>>>>>> The Tinn-R project sends messages to Rgui.exe (SDI mode) via the 
>>>>>>> Windows
>>>>>>> API's PostMessage function.
>>>>>>> A simplification of the code (in object Pascal) can be seen below.
>>>>>>>
>>>>>>> procedure TfMain.btnPasteClick(Sender: TObject);
>>>>>>> var
>>>>>>> ??? i: integer;
>>>>>>> ??? sTmp: WideString;
>>>>>>> ??? hBN: HWND;
>>>>>>>
>>>>>>> begin
>>>>>>> ??? hBN:= FindWindowA(nil,
>>>>>>> ????????????????????? 'R Console (64-bit)');
>>>>>>>
>>>>>>> ??? sTmp:= 'sd';
>>>>>>>
>>>>>>> ??? for i:= 1 to Length(sTmp) do begin
>>>>>>> ????? PostMessage(hBN,
>>>>>>> ????????????????? WM_CHAR,
>>>>>>> ????????????????? Ord(sTmp[i]),
>>>>>>> ????????????????? 0);
>>>>>>> ??? end;
>>>>>>>
>>>>>>> ??? PostMessage(hBN,
>>>>>>> ??????????????? WM_KEYDOWN,
>>>>>>> ??????????????? VK_RETURN, 0);
>>>>>>> end;
>>>>>>>
>>>>>>> This code has always worked fine for all versions of Rgui.exe 
>>>>>>> with the
>>>>>>> exception of the last one released, ie 4.2.0.
>>>>>>>
>>>>>>> We've been trying to get around the problem on the Object Pascal 
>>>>>>> side,
>>>>>>> but without success so far.
>>>>>>>
>>>>>>> Does anyone connected to the compilation of Rqui.exe know what the
>>>>>>> problem is?
>>>>>>
>>>>>> It could be that the new build enforces Windows security more 
>>>>>> stringently.? More details are described in the answer to this 
>>>>>> question: https://stackoverflow.com/a/40139498/2554330, but at a 
>>>>>> minimum you should be checking the return value from PostMessage.
>>>>>>
>>>>>> Duncan Murdoch
>>>>>>
>>>>>>>
>>>>>>> Best,
>>>>>>> ///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\
>>>>>>> Jose Claudio Faria
>>>>>>> UESC/DCET/Brasil
>>>>>>> joseclaudio.faria at gmail.com
>>>>>>> Telefones:
>>>>>>> 55(73)3680.5545 - UESC
>>>>>>> 55(73)99966.9100 - VIVO
>>>>>>> ///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\///\\\
>>>>>>> If you have software to deal with statistics, you have arms,
>>>>>>> if you have good software, you have arms and legs,
>>>>>>> if you have software like R, you have arms, legs and wings...
>>>>>>> the height of your flight depends only on you.
>>>>>>>
>>>>>>> ??? [[alternative HTML version deleted]]
>>>>>>>
>>>>>>> ______________________________________________
>>>>>>> R-devel at r-project.org mailing list
>>>>>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>>>>
>>>>>
>>>>> ______________________________________________
>>>>> R-devel at r-project.org mailing list
>>>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>



[Rd] Rgui.exe 4.2.0 does not receive characters via the Windows API's PostMessage function
Tomas Kalibera