質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

2136閲覧

スクリーンセーバーの解除方法が分からない

dem0nmichik0

総合スコア37

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

1グッド

0クリップ

投稿2019/05/11 04:39

編集2019/05/12 10:44

実現したいこと

「スクリーンセーバーがかかっている」かつ「フラグがON」のとき,「スクリーンセーバーを解除したい」です.

困っていること

現状,スクリーンセーバーの状態取得は「SystemParametersInfo」で,スクリーンセーバーの解除方法を下記二つで試しましたが,解除されなくて困っています.
1. SetCursoPos(x, y)でカーソルを任意の位置に移動
2. keybd_evnetでキーボードを押す/離す

修正後のソースコードでもスクリーンセーバーが解除しません.現状,スクリーンセーバーになることは確認しました.また,hdesk = OpenDesktop(L"Screen-saver", 0, FALSE, GENERIC_ALL);にbreakを貼って一行上の「hdesk = OpenDesktop(L"Screen-saver", 0, FALSE, GENERIC_ALL);の「hdesk」の状態をIDEのインスペクトで見てみると「????」となっていました.「OpenDesktop」について調べた結果,「Window Stationとデスクトップ - kkAyatakaのメモ帳。」に「OpenDesktop」は「WPFではうまくいかない.」とありました.WPFのことをあまり分かっていないのですが,C++Builderで作成したアプリケーションは「VCLアプリケーション」であり,WPFであるから大丈夫なのではないでしょうか?ご教授お願いいたします.

別に試したことは,C++BuilderのVCLアプリケーションが原因の可能性があるとおもったので,「screensaver.cpp」を作成後.C++Builderのコンパイラ(bcc32.exe)でコンパイルして実行した結果,下記のようになりました.
1. whileの中で「screenSaver」のみをコールした時はスクリーンセーバー抑止を確認.
2. whileの中で「SystemParametesInfo」の第三引数の状態が「true」なら「screenSaver」をコールした時はスクリーンセーバーはかかるが,スクリーンセーバーが解除されないことを確認.
「SystemParametersInfo」の使い方が間違っているのでしょうか?

修正後の「screensaver.cpp」ではbcc32.exeでコンパイルするときに「-tWM」オプションを付ければ,任意の動作(スクリーンセーバーがかかったあと,5秒後に解除される)になることを確認しました.
なので,その処理をC++Builder上で実現するために「Unit1.cpp」と「Unit1.h」を修正後,「Unit2.cpp」と「Unit2.h」を追加してC++Builder10.2のIDEでコンパイルしましたが次のエラーが出て困っています.
0. E2034 'void(void )'型は'void ()(void )'型に変換できない
0. E2342 パラメータ'__start’はvoid (
)(void *)型として定義されているのでvoid(__fastcall *)(void *)は渡せない

確認したこと(試したこと)

1. 「keybd_event( VK_ESCAPE, 0, KEYEVENTF_KEYUP, 0 );」にbreakを貼ってスクリーンセーバー後,5秒待っても解除されない(その後,マウスを動かしてスクリーンセーバーを解除.breakを貼った個所に処理が到達していることを確認.)
2. 1ではbreak時にまだ「keybd_event」処理を実行していないからその下の「ShowMessage("スクリーンセーバー解除したよ");」にbreakに貼ってスクリーンセーバー後,5秒待っても解除されない.
3. ボタンイベント実行時に「SetCursorPos」でマウスカーソル位置が指定位置に移動している.

###原因または解決方法
【原因】
「SetCursorPos」や「keybd_event」はWindows32APIだから64bitOSでは動作しないのではないか?でも,そうするとスクリーンセーバーがかかっていないときにボタンイベントで「SetCursorPos」でマウスカーソル位置が指定位置に移動していることが不思議でなりません.WIN32APIだから,スクリーンセーバーがかかていないときに使えても,スクリーンセーバーかかているときは使えないって言われれば,納得するのですが.
【解決方法】
リアルタイムでマウス座標を取得して,「スクリーンセーバーがかかっている」かつ「5秒後」のときに「マウスカーソルを移動する」でスクリーンセーバーを解除できると思っています.
リアルタイムでマウス座標を取得方法は分かりました(TPoint型のMouse->CursorPos).また,任意のマウス位置を設定する方法(SetLocation(x, y)メソッド)も分かりました.その後,マウスカーソルを移動する方法が分かりません.ご教授お願いいたします.

下記ソースの開発環境

OS:Windows10 64bit
IDE:Embarcadero® C++Builder 10.2
言語:C++

実際に実現するPCの開発環境(参考情報)

OS:Windows10 64bit
IDE:Embarcadero® C++Builder 10.3
言語:C++
開発環境のバージョンのみ異なります.

修正後のソースコード

「注意点」
「スクリーンセーバーがかかっている」かつ「フラグがON」のとき,「スクリーンセーバーを解除したい」と書きましたが,このソースコードではスクリーンセーバーがかかっているときに「フラグON」にすることができないので,「スクリーンセーバーがかかっている」かつ「5秒後」の条件でコーディングしています.
<Unit1.cpp>

C++

1//--------------------------------------------------------------------------- 2 3#include <vcl.h> 4#pragma hdrstop 5// コンパイルオプションの追加 6#pragma checkoption -tWM 7 8#include "unit1.h" 9#include "Unit2.h" 10#include <windows.h> 11#include <process.h> 12//--------------------------------------------------------------------------- 13#pragma package(smart_init) 14#pragma resource "*.dfm" 15TForm1 *Form1; 16//--------------------------------------------------------------------------- 17__fastcall TForm1::TForm1(TComponent* Owner) 18 : TForm(Owner) 19{ 20 cnt = 0; 21 screensaver = false; 22 Form1->Left = (Screen->Monitors[0]->Width / 2) - (Form1->Width / 2); 23 Form1->Top = (Screen->Monitors[0]->Height / 2) - (Form1->Height / 2); 24 memset( &hdesk, 0, sizeof(HDESK) ); 25 memset( &hdesk_old, 0, sizeof(HDESK) ); 26} 27//--------------------------------------------------------------------------- 28void __fastcall TForm1::Timer1Timer(TObject *Sender) 29{ 30 int x = 0; 31 int y = 0; 32 33 x = Form1->Width / 2; 34 y = Form1->Height / 2; 35 pt = Mouse->CursorPos; 36 37 Label1->Caption = "X座標:" + IntToStr((int)pt.X) + ", Y座標:" + IntToStr((int)pt.Y); 38 39 SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, (void *)&screensaver, 0); 40 if( screensaver == true) 41 { 42 // 5秒後(周期は500ms) 43 if( cnt >= 10 ) 44 { 45 // ウィンドウを作成するとSetThreadDesktopできないのでスレッドを起動 46 _beginthread(screenSaver, 0, NULL); 47 48 cnt = 0; 49 } 50 cnt++; 51 } 52} 53//--------------------------------------------------------------------------- 54void __fastcall TForm1::Button1Click(TObject *Sender) 55{ 56 int x = 0; 57 int y = 0; 58 59 x = Form1->Width / 2; 60 y = Form1->Height / 2; 61 SetCursorPos(x, y); 62} 63//--------------------------------------------------------------------------- 64

<Unit1.h>

C++

1//--------------------------------------------------------------------------- 2 3#ifndef Unit1H 4#define Unit1H 5//--------------------------------------------------------------------------- 6#include <System.Classes.hpp> 7#include <Vcl.Controls.hpp> 8#include <Vcl.StdCtrls.hpp> 9#include <Vcl.Forms.hpp> 10#include <Vcl.ExtCtrls.hpp> 11//--------------------------------------------------------------------------- 12class TForm1 : public TForm 13{ 14__published: // IDE で管理されるコンポーネント 15 TTimer *Timer1; 16 TLabel *Label1; 17 TButton *Button1; 18 void __fastcall Timer1Timer(TObject *Sender); 19 void __fastcall Button1Click(TObject *Sender); 20private: // ユーザー宣言 21public: // ユーザー宣言 22 __fastcall TForm1(TComponent* Owner); 23 24 TPoint pt; 25 bool screensaver; 26 int cnt; 27 HDESK hdesk; 28 HDESK hdesk_old; 29}; 30//--------------------------------------------------------------------------- 31extern PACKAGE TForm1 *Form1; 32//--------------------------------------------------------------------------- 33#endif

<Unit2.cpp>

c++

1//--------------------------------------------------------------------------- 2 3#pragma hdrstop 4 5#include "unit1.h" 6#include "Unit2.h" 7#include <windows.h> 8#include <process.h> 9//--------------------------------------------------------------------------- 10#pragma package(smart_init 11 12//--------------------------------------------------------------------------- 13//void __fastcall screenSaver(void *) 14void __fastcall screenSaver(void *a) 15{ 16 // 元のデスクトップハンドルを退避 17 hdesk_old = GetThreadDesktop(GetCurrentThreadId()); 18 19 // スクリーンセーバーのデスクトップを開く 20 hdesk = OpenDesktop(L"Screen-saver", 0, FALSE, GENERIC_ALL); 21 if( hdesk != NULL ) 22 { 23 // 現在のスレッドのデスクトップを変更 24 SetThreadDesktop(hdesk); 25 } 26 27 // スクリーンセーバー解除処理(キーボードの押す/離す) 28 keybd_event( VK_ESCAPE, 0, 0, 0 ); 29 keybd_event( VK_ESCAPE, 0, KEYEVENTF_KEYUP, 0 ); 30 31 // 元のデスクトップに戻す 32 SetThreadDesktop(hdesk_old); 33 if( hdesk != NULL ) 34 { 35 CloseDesktop(hdesk); 36 } 37} 38//---------------------------------------------------------------------------

<Unit2.h>

c++

1//--------------------------------------------------------------------------- 2 3#ifndef Unit2H 4#define Unit2H 5//--------------------------------------------------------------------------- 6 7// スクリーンセーバー解除 8void __fastcall screenSaver(void *); 9 10//--------------------------------------------------------------------------- 11#endif

<screensaver.cpp>

c++

1// 標準ヘッダー宣言 2#include <Windows.h> 3#include <process.h> 4 5// プロトタイプ宣言 6LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 7char szClassName[] = "ウィンドウクラス・ネーム"; 8void screenSaver(void *a); 9 10int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst, 11 LPSTR lpszCmdLine, int nCmdShow) 12{ 13 HWND hWnd; 14 MSG msg; 15 WNDCLASS myProg; 16 bool screensaver; 17 HDC hdc; 18 PAINTSTRUCT ps; 19 20 // ウィンドウ・クラスの登録 21 if( !hPreInst ) 22 { 23 myProg.style = CS_HREDRAW | CS_VREDRAW; 24 myProg.lpfnWndProc = WndProc; // プロシージャ名 25 myProg.cbClsExtra = 0; 26 myProg.cbWndExtra = 0; 27 myProg.hInstance = hInstance; // インスタンス 28 myProg.hIcon = NULL; 29 myProg.hCursor = LoadCursor(NULL, IDC_ARROW); 30 myProg.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 31 myProg.lpszMenuName = NULL; 32 myProg.lpszClassName = szClassName; 33 if( !RegisterClass(&myProg) ) 34 { 35 return (false); 36 } 37 } 38 39 // ウィンドウの生成 40 hWnd = CreateWindow(szClassName, 41 "猫でも分かるプログラミング", // タイトルバーにこの名前が表示される 42 WS_OVERLAPPEDWINDOW, // ウィンドウの種類 43 CW_USEDEFAULT, // X座標 44 CW_USEDEFAULT, // Y座標 45 CW_USEDEFAULT, // 幅 46 CW_USEDEFAULT, // 高さ 47 NULL, // 親ウィンドウのハンドル,親を作るときはNULL 48 NULL, // メニューハンドル,クラスメニューを使うときはNULL 49 hInstance, // インスタンスハンドル 50 NULL); 51 ShowWindow(hWnd, nCmdShow); 52 UpdateWindow(hWnd); 53 while( GetMessage(&msg, NULL, 0, 0) ) 54 { 55 TranslateMessage(&msg); 56 DispatchMessage(&msg); 57 // 下記モジュールのみをコールするだけだとスクリーンセーバーがかからないので, 58 // スクリーンセーバーの抑止(キーボードの押す/離す)していることを確認 59// screenSaver(hWnd); // スクリーンセーバーの解除 60 61 // スクリーンセーバー状態の取得 62 SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, (void *)&screensaver, 0); 63 // スクリーンセーバーが有効の場合 64 if( screensaver == true ) 65 { 66 // 5秒後 67 Sleep(5000); 68 69 // ウィンドウを作成するとSetThreadDesktopできないのでスレッドを起動する. 70 _beginthread(screenSaver, 0, NULL); 71 } 72 } 73 return (int)msg.wParam; 74} 75 76// ウィンドウプロシージャ 77LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 78{ 79 switch(msg) 80 { 81 case WM_DESTROY: 82 PostQuitMessage(0); 83 break; 84 default: 85 return (DefWindowProc(hWnd, msg, wParam, lParam)); 86 } 87 88 return (0L); 89} 90 91void screenSaver(void *a) 92{ 93 // 元のデスクトップハンドルを退避 94 HDESK hdesk_old = GetThreadDesktop(GetCurrentThreadId()); 95 // スクリーンセーバーのデスクトップを開く 96 HDESK hdesk = OpenDesktop("Screen-saver", 0, FALSE, GENERIC_ALL); 97 if( hdesk != NULL ) 98 { 99 // 現在のスレッドのデスクトップを変更 100 SetThreadDesktop(hdesk); 101 } 102 // スクリーンセーバー解除処理 103 keybd_event(VK_ESCAPE, 0, 0, 0); 104 keybd_event(VK_ESCAPE, 0, KEYEVENTF_KEYUP, 0); 105 106 // 元のデスクトップに戻す 107 SetThreadDesktop(hdesk_old); 108 if( hdesk != NULL ) 109 { 110 CloseDesktop(hdesk); 111 } 112 113} 114
atata0319👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Windows 標準のスクリーンセーバーは WM_KEYDOWN イベントでスクリーンセーブ状態が解除されるため、提示のコードでは解除できません。キーを押すことと離すことをエミュレートするために以下のようにする必要があります。

C

1keybd_event( VK_ESCAPE, 0, 0, 0 ); 2keybd_event( VK_ESCAPE, 0, KEYEVENTF_KEYUP, 0 );

ただし、上記のコードはスクリーンセーバーがプレビューモードで起動しているときか『再開時にログオン画面に戻る』設定が無効な場合のみ動作します。

スクリーンセーバーの設定
上図のように『再開時にログオン画面に戻る』設定が有効である場合、スクリーンセーバーは別デスクトップで動作するため、現在画面が起動しているデスクトップからキーボードイベントを送信することはできません。その場合、別デスクトップに対してキーボードイベントを送信する必要があるのですが、現在ログオンしているセッションとは別のセッションとなるため操作できない気がしました。試すのは面白そうな題材ではありますが。

あと、C++ Builder の IDE がそうだったかの記憶は昔過ぎてありませんが、VC++ の IDE はブレークポイントがヒットしている行のコードは未実行状態となります。ログに出力するなどの別の確認手段を持たれた方が良いかもしれません。ブレークポイントを使うのであれば仮想環境を用意するなりしてリモートデバッグで試されるのが良いかと思います。

余談ですが、20年ぐらい前に VC++ と BCB を比較したときに VC++ より BCB の方が Visual だなと思ったのが懐かしい記憶です。それ以来 C++ Builder は主を変え続ける状況になったのが残念なことです。


追記
どうやら通常起動時もスクリーンセーバーは別デスクトップで動作するようになっているようです。提示のコードでスクリーンセーバーを解除できるのはプレビューモード時のみでした。


追記2
コメントを受けて作成したコードになります。紆余曲折ありましたが、もっとも簡単そうなサンプルということでこのようになりました。Windows 10 ではこれでスクリーンセーバーを解除できています。なお、『再開時にログオン画面に戻る』設定が有効である場合もログオン画面までは表示されます。

C++

1#define UNICODE 2#include <windows.h> 3 4int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) 5{ 6 // スクリーンセーバー起動まで待機 7 Sleep(90000); 8 9 // 元のデスクトップハンドルを退避しておく。 10 HDESK hdeskOld = GetThreadDesktop(GetCurrentThreadId()); 11 12 // スクリーンセーバーのデスクトップを開く 13 HDESK hdesk = OpenDesktop(L"Screen-saver", 0, FALSE, GENERIC_ALL); 14 if (hdesk != NULL) 15 { 16 // 現在のスレッドのデスクトップを変更 17 SetThreadDesktop(hdesk); 18 } 19 20 // スクリーンセーバー解除処理を実施 21 keybd_event(VK_ESCAPE, 0, 0, 0); 22 keybd_event(VK_ESCAPE, 0, KEYEVENTF_KEYUP, 0); 23 24 // 元のデスクトップに戻す。 25 SetThreadDesktop(hdeskOld); 26 27 if (hdesk != NULL) 28 { 29 CloseDesktop(hdesk); 30 } 31 32 return 0; 33}

考えてみたら質問者が作成されているプログラムは Windows アプリであるためデスクトップを切り替えた後、元に戻さないと正しく動作しないので、その処理も組み込んであります。スレッド単位での切り替えになるので、スクリーンセーバー解除処理だけを別スレッドで実行しても良いかと思います。


追記3
あまり使わない API だったのですっかり忘れてましたが、一回ウィンドウ作成したら SetThreadDesktop は失敗します。この場合、別スレッドが必須でした。昔の C++ Builder でも _beginthread は有効でしたので、VC++ のコードのまま提示します。

C++

1// 標準ヘッダー宣言 2#include <windows.h> 3#include <process.h> 4 5// プロトタイプ宣言 6LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); 7char szClassName[] = "ウィンドウクラス・ネーム"; 8void screenSaver(void*); 9 10int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInst, 11 LPSTR lpszCmdLine, int nCmdShow) 12{ 13 HWND hWnd; 14 MSG msg; 15 WNDCLASS myProg; 16 bool screensaver; 17 HDC hdc; 18 PAINTSTRUCT ps; 19 20 // ウィンドウ・クラスの登録 21 if (!hPreInst) 22 { 23 myProg.style = CS_HREDRAW | CS_VREDRAW; 24 myProg.lpfnWndProc = WndProc; // プロシージャ名 25 myProg.cbClsExtra = 0; 26 myProg.cbWndExtra = 0; 27 myProg.hInstance = hInstance; // インスタンス 28 myProg.hIcon = NULL; 29 myProg.hCursor = LoadCursor(NULL, IDC_ARROW); 30 myProg.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 31 myProg.lpszMenuName = NULL; 32 myProg.lpszClassName = szClassName; 33 if (!RegisterClass(&myProg)) 34 { 35 return (false); 36 } 37 } 38 39 // ウィンドウの生成 40 hWnd = CreateWindow(szClassName, 41 "猫でも分かるプログラミング", // タイトルバーにこの名前が表示される 42 WS_OVERLAPPEDWINDOW, // ウィンドウの種類 43 CW_USEDEFAULT, // X座標 44 CW_USEDEFAULT, // Y座標 45 CW_USEDEFAULT, // 幅 46 CW_USEDEFAULT, // 高さ 47 NULL, // 親ウィンドウのハンドル,親を作るときはNULL 48 NULL, // メニューハンドル,クラスメニューを使うときはNULL 49 hInstance, // インスタンスハンドル 50 NULL); 51 ShowWindow(hWnd, nCmdShow); 52 UpdateWindow(hWnd); 53 while (GetMessage(&msg, NULL, 0, 0)) 54 { 55 TranslateMessage(&msg); 56 DispatchMessage(&msg); 57 // 下記モジュールのみをコールするだけだとスクリーンセーバーがかからないので, 58 // スクリーンセーバーの抑止(キーボードの押す/離す)していることを確認 59// screenSaver(hWnd); // スクリーンセーバーの解除 60 61 // スクリーンセーバー状態の取得 62 SystemParametersInfo(SPI_GETSCREENSAVERRUNNING, 0, (void *)&screensaver, 0); 63 // SystemParametersInfo(SPI_GETSCREENSAVEACTIVE, 0, (void *)&screensaver, 0); 64 // スクリーンセーバーが有効の場合 65 if (screensaver == true) 66 { 67 // 5秒後 68 Sleep(5000); 69 70 // ウィンドウを作成すると SetThreadDesktop できないのでスレッドを起動する。 71 _beginthread(screenSaver, 0, NULL); 72 } 73 } 74 return (int)msg.wParam; 75} 76 77// ウィンドウプロシージャ 78LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 79{ 80 switch (msg) 81 { 82 case WM_DESTROY: 83 PostQuitMessage(0); 84 break; 85 default: 86 return (DefWindowProc(hWnd, msg, wParam, lParam)); 87 } 88 89 return (0L); 90} 91 92void screenSaver(void*) 93{ 94 // 元のデスクトップハンドルを退避 95 HDESK hdesk_old = GetThreadDesktop(GetCurrentThreadId()); 96 // スクリーンセーバーのデスクトップを開く 97// HDESK hdesk = OpenDesktop(L"Screen-saver", 0, FALSE, GENERIC_ALL); 98 HDESK hdesk = OpenDesktop("Screen-saver", 0, FALSE, GENERIC_ALL); 99 if (hdesk != NULL) 100 { 101 // 現在のスレッドのデスクトップを変更 102 SetThreadDesktop(hdesk); 103 } 104 // スクリーンセーバー解除処理 105 keybd_event(VK_ESCAPE, 0, 0, 0); 106 keybd_event(VK_ESCAPE, 0, KEYEVENTF_KEYUP, 0); 107 108 // 元のデスクトップに戻す 109 SetThreadDesktop(hdesk_old); 110 if (hdesk != NULL) 111 { 112 CloseDesktop(hdesk); 113 } 114 115}

追記4
もはや C++ Builder の話なので別質問を立ててもらった方が良いと思いますが、内容が少ないので合わせて回答します。
C++ Builder のリファレンスでは以下のように定義されています。

C++

1unsigned long _beginthread(void (_USERENTRY *__start)(void *), unsigned __stksize, void *__arg);

見ていただくとわかる通り ____fastcall ではありません。該当ページのサンプルにならって ____fastcall を外していただければ問題ないかと思います。

投稿2019/05/11 05:38

編集2019/05/12 10:57
atata0319

総合スコア881

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2019/05/11 06:29 編集

> 現在ログオンしているセッションとは別のセッションとなるため操作できない気が やるとすれば、スクリーンセーバー用のデスクトップの名前は"Screen-saver"で、同じセッション/ウィンドウステーションである限りその名前でOpenDesktopし、それに対してSetThreadDestopで現スレッドを潜り込ませて処理をするような形だったかと思います。ただ、"Screen-saver"デスクトップ自体のアクセス権がそれを許さないようになっていると別プロセスからは無理かもしれませんし、最新のWindowsではまた事情が異なってきているかもしれません。
atata0319

2019/05/11 06:52 編集

Windows 10 で CreateProcess で該当のウィンドウステーション/デスクトップに直接プロセスを起動する方法を試してみたところ通常プロセスからは管理者権限を持たせてもアクセス不能でした。OpenWindowStation/OpenDesktop + SetProcessWindowStation/SetThreadDesktop を試してみてそれがダメなら対話型サービスから試してみるぐらいですかね。
atata0319

2019/05/11 07:35 編集

と思ったらいけました。"Screen-saver" デスクトップではなく該当のウィンドウステーションの "Winlogon" デスクトップの方を指定していました。これはログオン画面用でしたね。
atata0319

2019/05/11 07:32

dodox86 さん。ありがとうございました。とりあえず、動作するコードはできました。
dodox86

2019/05/11 08:27 編集

なんと素早い対応。参考になります。こちらでもご提示のコードで動作を確認させていただきました。プログラムは32ビットビルドで、Win.7 SP1と10(バージョン1709)、いずれも64ビット版で動作OKでした。
dem0nmichik0

2019/05/11 16:30

atata0319さん,dodox86さん,回答ありがとうございます. 試してみましたが,スクリーンセーバーは解除されませんでした.質問フォームを更新しましたがC++Builder(VCLアプリケーション?)のせいと思ったので,猫でも分かるプログラミングを参考にしたGUIアプリケーションにしたらスクリーンセーバーは抑止されました.ですが,スクリーンセーバーになってから教えていただいたコードをコールするとスクリーンセーバーが解除されなくて困っています.
atata0319

2019/05/11 17:53

回答追記しました。やはり元のコードで試さないとだめですね。私が所有している C++ Builder はボーランド時代のものなので、今は動作するかわかりませんが・・・。
dem0nmichik0

2019/05/12 10:49

atata0319さん,回答ありがとうございます. VC++コードのほうをVisualStudio2017とbcc32のコンパイラを使って実行したところ,自分の意図した動作になりました.ありがとうございます. その後,そのコードをC++Builderに移植したのですがエラーが出力されて困っています.時間がありましたらご教授お願いいたします.質問フォームに修正後のソースコードとエラー内容を挙げてあります. 引き続き自分でも調べます.
atata0319

2019/05/12 10:58

追記しました。
dem0nmichik0

2019/05/12 11:32

atata0319さん,回答ありがとうございます. 回答およびURLを参考にやってみます.この度はありがとうございました.
dem0nmichik0

2019/05/12 11:58

atata0319さん C++Builderで意図した動作のプログラムができました. OpenDesktopなど知らないAPIも知ることができてとても良かったです. いろいろありがとうございました.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問