Tomas Kalibera
2022-May-16 17:21 UTC
[Rd] Rgui.exe 4.2.0 does not receive characters via the Windows API's PostMessage function
Dear Jose, On 5/15/22 01:31, jcfaria wrote:> Dear Tomas, > > I am very grateful for your attention! > > I've been reading some things about the GraphApp > toolkit(http://enchantia.com/software/graphapp/) that is being used in > the development of new versions of Rgui. > > Really, if it's a matter of choice, the problems I reported cannot be > considered a "bug". It's up to us - GUI and IDE application developers > - to adapt to the new features. > > I'm studying how to get around the problem, but I still haven't found > a simple way. > > The solution you proposed (code below) ran fine here in all versions > of Rgui I have installed, but it's working only for very simple > strings, like the one I tested. When testing the needs close to the > real I found some problems. > > For example, when sending the string below: > - char *s = "(s <- c('?', 'b', 'c', '?'))"; > > Rgui receives: > > 9s ,- c9'', 'b', 'c', ''00 > Error: unexpected symbol in "9s" > > > > > #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; > ?? } > > ?? //Samples to send: > // char *s = "sd"; > ?? char *s = "(s <- c('?', 'b', 'c', '?'))"; > > ?? for(i = 0; i < strlen(s); i++) { > ???? res = PostMessage(hw, WM_KEYDOWN, VkKeyScan(s[i]), 0); > ???? printf("Sending char %c: %d.\n", s[i], res); > ?? } > > ?? res = PostMessage(hw, WM_KEYDOWN, VK_RETURN, 0); > ?? printf("Sending return: %d\n.", res); > ?? return 0; > } > > The idea of Tinn-R communicating with Rgui.exe is to take advantage of > the great stability of Rgui. Since communication with Rterm is done > via pipe. > > I believe that developing a new interface using the resources of the > R.dll library, as proposed, is outside the simple purposes of the > Tinn-R project. > > Any help in this regard is welcome.If embedding R seems too involved, and the hack above doesn't work well enough, perhaps you could use SendInput() (also mentioned in the blog post [1] below as a more correct way to inject input as WM_KEYDOWN).? This is an example: --- #include <windows.h> #include <stdio.h> int main(int argc, char **argv) { ? HWND hw, ow; ? int i, res; ? hw = FindWindow(NULL, "R Console (64-bit)"); ? if (hw == NULL) { ??? printf("Could not get Rgui window: %x\n", GetLastError()); ??? return 2; ? } ? ow = GetForegroundWindow(); ? if (ow == NULL) ??? printf("Foreground window is NULL\n"); ? if (!SetForegroundWindow(hw)) ??? printf("Could not set Rgui as foreground window\n"); ? char *sd = "sd"; ? for(i = 0; i < strlen(sd); i++) { ??? INPUT input; ??? ZeroMemory(&input, sizeof(INPUT)); ??? input.type = INPUT_KEYBOARD; ??? input.ki.dwFlags = KEYEVENTF_UNICODE; ??? input.ki.wScan = (unsigned) sd[i]; ??? res = SendInput(1, &input, sizeof(INPUT)); ??? printf("Sending char %c (%x): %d.\n", sd[i], sd[i], res); ? } ? { ??? INPUT input[2]; ??? ZeroMemory(input, 2*sizeof(INPUT)); ??? input[0].type = input[1].type = INPUT_KEYBOARD; ??? input[1].ki.dwFlags = KEYEVENTF_KEYUP; ??? input[0].ki.wVk = input[1].ki.wVk = VK_RETURN; ??? res = SendInput(2, input, sizeof(INPUT)); ??? printf("Sending return: %d.\n", res); ? } ? if (!SetForegroundWindow(ow)) ??? printf("Could not set the original window as foreground"); ? return 0; } --- This example works for me with R 4.1.3 and with R-devel 82368. It doesn't work with R 4.2.0 (see a related thread about Dasher on this list). 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: "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): 11/05/2022 13:32:23 > Assunto: Re: [Rd] Rgui.exe 4.2.0 does not receive characters via the > Windows API's PostMessage function > >> >> 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 >>>>> >
Tomas Kalibera
2022-May-24 07:34 UTC
[Rd] Rgui.exe 4.2.0 does not receive characters via the Windows API's PostMessage function
On 5/16/22 19:21, Tomas Kalibera wrote:> Dear Jose, > > On 5/15/22 01:31, jcfaria wrote: >> Dear Tomas, >> >> I am very grateful for your attention! >> >> I've been reading some things about the GraphApp >> toolkit(http://enchantia.com/software/graphapp/) that is being used >> in the development of new versions of Rgui. >> >> Really, if it's a matter of choice, the problems I reported cannot be >> considered a "bug". It's up to us - GUI and IDE application >> developers - to adapt to the new features. >> >> I'm studying how to get around the problem, but I still haven't found >> a simple way. >> >> The solution you proposed (code below) ran fine here in all versions >> of Rgui I have installed, but it's working only for very simple >> strings, like the one I tested. When testing the needs close to the >> real I found some problems. >> >> For example, when sending the string below: >> - char *s = "(s <- c('?', 'b', 'c', '?'))"; >> >> Rgui receives: >> > 9s ,- c9'', 'b', 'c', ''00 >> Error: unexpected symbol in "9s" >> > >> >> >> #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; >> ?? } >> >> ?? //Samples to send: >> // char *s = "sd"; >> ?? char *s = "(s <- c('?', 'b', 'c', '?'))"; >> >> ?? for(i = 0; i < strlen(s); i++) { >> ???? res = PostMessage(hw, WM_KEYDOWN, VkKeyScan(s[i]), 0); >> ???? printf("Sending char %c: %d.\n", s[i], res); >> ?? } >> >> ?? res = PostMessage(hw, WM_KEYDOWN, VK_RETURN, 0); >> ?? printf("Sending return: %d\n.", res); >> ?? return 0; >> } >> >> The idea of Tinn-R communicating with Rgui.exe is to take advantage >> of the great stability of Rgui. Since communication with Rterm is >> done via pipe. >> >> I believe that developing a new interface using the resources of the >> R.dll library, as proposed, is outside the simple purposes of the >> Tinn-R project. >> >> Any help in this regard is welcome. > > If embedding R seems too involved, and the hack above doesn't work > well enough, perhaps you could use SendInput() (also mentioned in the > blog post [1] below as a more correct way to inject input as > WM_KEYDOWN).? This is an example: > > --- > > #include <windows.h> > #include <stdio.h> > > int main(int argc, char **argv) { > ? HWND hw, ow; > ? int i, res; > > ? hw = FindWindow(NULL, "R Console (64-bit)"); > ? if (hw == NULL) { > ??? printf("Could not get Rgui window: %x\n", GetLastError()); > ??? return 2; > ? } > > ? ow = GetForegroundWindow(); > ? if (ow == NULL) > ??? printf("Foreground window is NULL\n"); > > ? if (!SetForegroundWindow(hw)) > ??? printf("Could not set Rgui as foreground window\n"); > > ? char *sd = "sd"; > ? for(i = 0; i < strlen(sd); i++) { > ??? INPUT input; > > ??? ZeroMemory(&input, sizeof(INPUT)); > ??? input.type = INPUT_KEYBOARD; > ??? input.ki.dwFlags = KEYEVENTF_UNICODE; > ??? input.ki.wScan = (unsigned) sd[i]; > ??? res = SendInput(1, &input, sizeof(INPUT)); > > ??? printf("Sending char %c (%x): %d.\n", sd[i], sd[i], res); > ? } > > ? { > ??? INPUT input[2]; > > ??? ZeroMemory(input, 2*sizeof(INPUT)); > ??? input[0].type = input[1].type = INPUT_KEYBOARD; > ??? input[1].ki.dwFlags = KEYEVENTF_KEYUP; > ??? input[0].ki.wVk = input[1].ki.wVk = VK_RETURN; > ??? res = SendInput(2, input, sizeof(INPUT)); > ??? printf("Sending return: %d.\n", res); > ? } > > ? if (!SetForegroundWindow(ow)) > ??? printf("Could not set the original window as foreground"); > > ? return 0; > }Dear Jose, to send non-ASCII and repeated characters, you can modify the loop above as follows (use wchar_t to send Unicode characters, send also KEYEVENTF_KEYUP events to ensure that repeated characters such as ')' in the example are received). Otherwise, please refer to the MSDN documentation. ? wchar_t *sd = L"(s <- c('?', 'b', 'c', '?'))"; ? for(i = 0; i < wcslen(sd); i++) { ??? INPUT input; ??? ZeroMemory(&input, sizeof(INPUT)); ??? input.type = INPUT_KEYBOARD; ??? input.ki.dwFlags = KEYEVENTF_UNICODE; ??? input.ki.wScan = (unsigned) sd[i]; ??? res1 = SendInput(1, &input, sizeof(INPUT)); ??? ZeroMemory(&input, sizeof(INPUT)); ??? input.type = INPUT_KEYBOARD; ??? input.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP; ??? input.ki.wScan = (unsigned) sd[i]; ??? res2 = SendInput(1, &input, sizeof(INPUT)); ??? printf("Sending char %lc (%x): %d,%d .\n", sd[i], sd[i], res1, res2); ? } Best Tomas> > --- > > This example works for me with R 4.1.3 and with R-devel 82368. It > doesn't work with R 4.2.0 (see a related thread about Dasher on this > list). > > 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: "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): 11/05/2022 13:32:23 >> Assunto: Re: [Rd] Rgui.exe 4.2.0 does not receive characters via the >> Windows API's PostMessage function >> >>> >>> 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 >>>>>> >>