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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Win32 API

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

C++

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

Q&A

解決済

1回答

1365閲覧

WinAPI Clipboard IllustratorやExcel等の固有データが取り出せない

Weapon

総合スコア106

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Win32 API

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

C++

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

0グッド

0クリップ

投稿2018/12/05 13:37

前提・実現したいこと

以前の質問teratail:WinAPI Clipboard のFile Contentが取得できないから一旦File Contentはifで回避して少しは安定したAnalyzerになったと思いましたがIllustratorやExcelなどのパスやセルをコピーするとおそらくGlobalSize()の取得ができません.以前の質問のshlobj.h headerのカバー範囲ではないと思いますしハンドルは取得できているようなので扱いに処理の案が思いつきません.どこが問題かよろしくお願いします.

該当のソースコード

C

1//ClipBoardElement.cpp 2#ifndef UNICODE 3#define UNICODE 4#endif 5 6#include <windows.h> 7#include "ClipBoardElement.h" 8 9size_t SizeElement(int); 10 11DWORD GetClipboardElement(HWND hwnd, LPWSTR* lpp) { 12 OpenClipboard(hwnd); 13 14 int countelement = CountClipboardFormats(); 15 16 CBCONTENT* cbform = (CBCONTENT*)malloc(countelement * sizeof(CBCONTENT)); 17 18 int format = EnumClipboardFormats(0); 19 20 for (int cb = 0; cb < countelement; cb++) { 21 switch (format) { 22 case CF_TEXT: 23 wcscpy_s(cbform[cb].wFileName, L"CF_TEXT"); 24 break; 25 case CF_BITMAP: 26 wcscpy_s(cbform[cb].wFileName, L"CF_BITMAP"); 27 break; 28 case CF_METAFILEPICT: 29 wcscpy_s(cbform[cb].wFileName, L"CF_METAFILEPICT"); 30 break; 31 case CF_SYLK: 32 wcscpy_s(cbform[cb].wFileName, L"CF_SYLK"); 33 break; 34 case CF_DIF: 35 wcscpy_s(cbform[cb].wFileName, L"CF_DIF"); 36 break; 37 case CF_TIFF: 38 wcscpy_s(cbform[cb].wFileName, L"CF_TIFF"); 39 break; 40 case CF_OEMTEXT: 41 wcscpy_s(cbform[cb].wFileName, L"CF_OEMTEXT"); 42 break; 43 case CF_DIB: 44 wcscpy_s(cbform[cb].wFileName, L"CF_DIB"); 45 break; 46 case CF_PALETTE: 47 wcscpy_s(cbform[cb].wFileName, L"CF_PALETTE"); 48 break; 49 case CF_PENDATA: 50 wcscpy_s(cbform[cb].wFileName, L"CF_PENDATA"); 51 break; 52 case CF_RIFF: 53 wcscpy_s(cbform[cb].wFileName, L"CF_RIFF"); 54 break; 55 case CF_WAVE: 56 wcscpy_s(cbform[cb].wFileName, L"CF_WAVE"); 57 break; 58 case CF_UNICODETEXT: 59 wcscpy_s(cbform[cb].wFileName, L"CF_UNICODETEXT"); 60 break; 61 case CF_ENHMETAFILE: 62 wcscpy_s(cbform[cb].wFileName, L"CF_ENHMETAFILE"); 63 break; 64 case CF_HDROP: 65 wcscpy_s(cbform[cb].wFileName, L"CF_HDROP"); 66 break; 67 case CF_LOCALE: 68 wcscpy_s(cbform[cb].wFileName, L"CF_LOCALE"); 69 break; 70 case CF_MAX: 71 wcscpy_s(cbform[cb].wFileName, L"CF_MAX"); 72 break; 73 case CF_OWNERDISPLAY: 74 wcscpy_s(cbform[cb].wFileName, L"CF_OWNERDISPLAY"); 75 break; 76 case CF_DSPTEXT: 77 wcscpy_s(cbform[cb].wFileName, L"CF_DSPTEXT"); 78 break; 79 case CF_DSPBITMAP: 80 wcscpy_s(cbform[cb].wFileName, L"CF_DSPBITMAP"); 81 break; 82 case CF_DSPMETAFILEPICT: 83 wcscpy_s(cbform[cb].wFileName, L"CF_DSPMETAFILEPICT"); 84 break; 85 case CF_DSPENHMETAFILE: 86 wcscpy_s(cbform[cb].wFileName, L"CF_DSPENHMETAFILE"); 87 break; 88 default: 89 GetClipboardFormatName(format, cbform[cb].wFileName, 1024); 90 } 91 cbform[cb].iElemName = format; 92 cbform[cb].ElemSize = SizeElement(format); 93 94 format = EnumClipboardFormats(format); 95 } 96 97 size_t size = 0; 98 for (int cb = 0; cb < countelement; cb++) { 99 size_t tmpsize; 100 if (cbform[cb].ElemSize != 0) { 101 tmpsize = cbform[cb].ElemSize; 102 wchar_t messageid[1024]; 103 wsprintf(messageid, L"%d\nint Name : %x\nwide Name : %s\nsize : %d", cb, cbform[cb].iElemName, cbform[cb].wFileName, cbform[cb].ElemSize); 104 MessageBox(hwnd, messageid, L"ALERT", MB_OK); 105 } 106 else { 107 tmpsize = lstrlen(L"Unavailable Value"); 108 wchar_t messageid[1024]; 109 wsprintf(messageid, L"%d\nint Name : %x\nwide Name : %s\nsize : 0", cb, cbform[cb].iElemName, cbform[cb].wFileName); 110 MessageBox(hwnd, messageid, L"ALERT", MB_OK); 111 } 112 size += tmpsize; 113 } 114 115 wchar_t parameter_in_breaking[1024]; 116 wsprintf(parameter_in_breaking, L"size : %d\ncountelement : %d", size, countelement); 117 MessageBox(hwnd, parameter_in_breaking, L"ALERT", MB_OK); 118 119 size_t countofchar = (size + countelement * 6 + 1) * sizeof(wchar_t); 120 121 LPWSTR lp = (*lpp = (LPWSTR)calloc(countofchar, sizeof(wchar_t))); 122 if (!lp)return -1; 123 124 wcscat_s(lp, countofchar, L"\0"); 125 126 for (int cb = 0; cb < countelement; cb++) { 127 wcscat_s(lp, countofchar, cbform[cb].wFileName); 128 wcscat_s(lp, countofchar, L"\n"); 129 if (cbform[cb].ElemSize != 0) { 130 HGLOBAL hg = GetClipboardData(cbform[cb].iElemName); 131 wcscat_s(lp, countofchar, (LPWSTR)GlobalLock(hg)); 132 GlobalUnlock(hg); 133 } 134 else { 135 wcscat_s(lp, countofchar, L"Unavailable Value"); 136 } 137 wcscat_s(lp, countofchar, L"\n\n"); 138 } 139 140 CloseClipboard(); 141 free(cbform); 142 143 return 0; 144} 145 146size_t SizeElement(int format) { 147 HGLOBAL hg = GetClipboardData(format); 148 149 if (hg == NULL) { 150 wchar_t messageinf[512]; 151 wsprintf(messageinf, L"int %d\nCouldn't get the HGLOBAL",format); 152 MessageBox(NULL, messageinf, L"ALERT", MB_OK); 153 return 0; 154 } 155 else if (GlobalSize(hg) == 0) { 156 wchar_t messageinf[512]; 157 wsprintf(messageinf, L"int %d\nCouldn't get the GlobalSize", format); 158 MessageBox(NULL, messageinf, L"ALERT", MB_OK); 159 return 0; 160 }else return GlobalSize(hg); 161}

その他のコード

以前の質問のリンク先と同様のものです.

C

1//ClipBoardElement.h 2#pragma once 3#include <windows.h> 4 5typedef struct _tagCBCONTENT { 6 wchar_t wFileName[1024]; 7 int iElemName; 8 size_t ElemSize; 9}CBCONTENT; 10 11DWORD GetClipboardElement(HWND hwnd, LPWSTR* lpp);

C

1//main 2#define UNICODE 3 4#include <windows.h> 5#include "ClipBoardElement.h" 6 7#define ID_PASTE 10001 8 9LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 10 11int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpszCmdLine, int nCmdShow) 12{ 13 UNREFERENCED_PARAMETER(hPrevInstance); 14 UNREFERENCED_PARAMETER(lpszCmdLine); 15 16 wchar_t CLASS_NAME[] = L"sample"; 17 18 WNDCLASSEX wc = { 19 sizeof(WNDCLASSEX),CS_VREDRAW | CS_HREDRAW, WindowProc, 20 0, 0, hInstance, 21 NULL, (HCURSOR)LoadImage(NULL, IDC_ARROW, IMAGE_CURSOR, 0, 0, LR_SHARED),(HBRUSH)GetStockObject(WHITE_BRUSH), 22 NULL, CLASS_NAME, NULL 23 }; 24 25 RegisterClassEx(&wc); 26 27 HWND hwnd = CreateWindowEx( 28 0, CLASS_NAME, L"ClipBoard Analyzer", WS_OVERLAPPEDWINDOW, 29 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 30 NULL, NULL, hInstance, NULL); 31 if (hwnd == NULL)return 0; 32 33 static ACCEL accel[1]; 34 accel[0].key = 0x56; 35 accel[0].cmd = ID_PASTE; 36 accel[0].fVirt = FCONTROL | FVIRTKEY; 37 38 HACCEL haccel = CreateAcceleratorTable(accel, 1); 39 40 ShowWindow(hwnd, nCmdShow); 41 UpdateWindow(hwnd); 42 43 MSG msg = {}; 44 while (GetMessage(&msg, NULL, 0, 0) > 0) { 45 if (!TranslateAccelerator(hwnd, haccel, &msg)) { 46 TranslateMessage(&msg); 47 DispatchMessage(&msg); 48 } 49 } 50 51 DestroyAcceleratorTable(haccel); 52 53 return (int)msg.wParam; 54} 55 56LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 57{ 58 static RECT rc; 59 60 switch (uMsg) { 61 case WM_CREATE: 62 static LPWSTR str; 63 64 break; 65 66 case WM_COMMAND: 67 if (LOWORD(wParam) == ID_PASTE) 68 { 69 if (str != NULL)free(str); 70 GetClipboardElement(hwnd, &str); 71 InvalidateRect(hwnd, NULL, TRUE); 72 } 73 74 break; 75 76 case WM_PAINT: 77 { 78 PAINTSTRUCT ps = {}; 79 HDC hdc = GetDC(hwnd); 80 81 BeginPaint(hwnd, &ps); 82 GetClientRect(hwnd, &rc); 83 DrawText(hdc, str, -1, &rc, DT_LEFT); 84 EndPaint(hwnd, &ps); 85 } 86 break; 87 88 case WM_DESTROY: 89 if (str != NULL)free(str); 90 91 PostQuitMessage(0); 92 return 0; 93 94 default: 95 break; 96 } 97 98 return DefWindowProc(hwnd, uMsg, wParam, lParam); 99}

補足情報

Windows10 Pro
VisualStudio2017 Community

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

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

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

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

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

guest

回答1

0

ベストアンサー

GetClipboardData で取得できるハンドルはグローバルメモリオブジェクトのハンドルだけではありません。以下の文書が示すように GDI オブジェクトのハンドルが取れることがあります。
Standard Clipboard Formats
https://docs.microsoft.com/en-us/windows/desktop/dataxchg/standard-clipboard-formats

上記とは関係ありませんが、shlobj.h の内容については以下のページで解説されています。
Shell Clipboard Formats
https://docs.microsoft.com/en-us/windows/desktop/shell/clipboard

これ以外に OLE のクリップボードフォーマットがあるのですが、1ページにまとまってないのでリンクを貼り付けるのは諦めました。

それらを踏まえて処理内容としては GlobalSize でサイズが取得できなかった場合、グローバルメモリオブジェクトではなく GDI オブジェクトであると仮定して GetObjectType で GDI オブジェクトの種類を取得してみるというのが良いのではないでしょうか?
EnumClipboardFormats で返されるクリップボードフォーマットの型で判断するのではなく、上記関数の呼び出し結果によって判断することになるかと思います。なお、アプリケーション独自のクリップボードフォーマットはすべてが公開されているわけではないので、アプリケーション毎に処理できないものは今後も発生しえます。上記の 2 種類以外で取得できないものは対応しないというのも 1 つの選択肢となります。

投稿2018/12/05 16:44

編集2018/12/05 17:34
atata0319

総合スコア881

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問