- ホーム
- win32sdk
- Copyしたセルを小ウィンドウに最前面表示
Excelでコピーしたセルをクリップボード経由で最前面表示する(番外品のカテから移設)
Excelでコピーしたセルを小ウィンドウで最前面表示するツールを作ってみました
Excelからクリップボードにコピーされる多彩な形式の内、emf形式を利用しています
VisualStudio2005のC++で作っていますが、きっとCの機能しか使っていません。
今まではVixの機能を使っていましたが、もっと軽く簡便なものがほしくなったものです。ファイルサイズ10KBと極軽量です。
基本的なWindow生成のスケルトンは「猫でもわかるWindowsプログラミング2版」と作者のサイトの、
ユニコード対応のコードを利用させてもらっています。
※更新機能を削除して、クリップボードにemfが無いときは終了する仕様に変更しました。
//Excelでコピーしたセル範囲を最前面のウィンドウに表示する
#define STRICT
#include <windows.h>
#include "resource.h"
#include <tchar.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
ATOM InitApp(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);
BOOL PlayEnhMetaFileAtOriginalSize( HDC, HENHMETAFILE);
TCHAR szClassName[] = TEXT("clip02");
HENHMETAFILE hEmf;
//ウィンドウクラス
int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst,
LPSTR lpsCmdLine, int nCmdShow)
{
MSG msg;
BOOL bRet;
if (!InitApp(hCurInst))
return FALSE;
if (!InitInstance(hCurInst, nCmdShow))
return FALSE;
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) {
if (bRet == -1) {
break;
} else {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int)msg.wParam;
}
//ウィンドウ・クラスの登録
ATOM InitApp(HINSTANCE hInst)
{
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WndProc; //プロシージャ名
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;//インスタンス
wc.hIcon = (HICON)LoadImage(NULL,
MAKEINTRESOURCE(IDI_ICON1), //IDI_APPLICATION
IMAGE_ICON,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);
wc.hCursor = (HCURSOR)LoadImage(NULL,
MAKEINTRESOURCE(IDC_ARROW),
IMAGE_CURSOR,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);
wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = TEXT("MYMENU"); //メニュー名
wc.lpszClassName = (LPCTSTR)szClassName;
wc.hIconSm = (HICON)LoadImage(NULL,
MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON,
0,
0,
LR_DEFAULTSIZE | LR_SHARED);
return (RegisterClassEx(&wc));
}
//ウィンドウの生成
BOOL InitInstance(HINSTANCE hInst, int nCmdShow)
{
HWND hWnd;
hWnd = CreateWindow(szClassName,
TEXT("ClipBoardのEMF表示"), //タイトルバーにこの名前が表示されます
WS_OVERLAPPEDWINDOW, //ウィンドウの種類
CW_USEDEFAULT, //X座標
CW_USEDEFAULT, //Y座標
200, //幅 CW_USEDEFAULT
100, //高さ CW_USEDEFAULT
NULL, //親ウィンドウのハンドル、親を作るときはNULL
NULL, //メニューハンドル、クラスメニューを使うときはNULL
hInst, //インスタンスハンドル
NULL);
if (!hWnd)
return FALSE;
//
SetWindowPos( hWnd, HWND_TOPMOST, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOSIZE );
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
HDC hdc;
PAINTSTRUCT ps;
switch (msg) {
case WM_CREATE:
ENHMETAHEADER emh;
HDC hDCdesktop;
RECT rect_win;
RECT rect_cli;
float PixelsX, PixelsY;
int wwidth, wheight;
int flamewx, flamewy;
if (IsClipboardFormatAvailable(CF_ENHMETAFILE)){
OpenClipboard(hWnd);
hEmf = (HENHMETAFILE)GetClipboardData(CF_ENHMETAFILE);
// Get the header from the enhanced metafile
ZeroMemory( &emh, sizeof(ENHMETAHEADER) );
emh.nSize = sizeof(ENHMETAHEADER);
GetEnhMetaFileHeader( hEmf, sizeof( ENHMETAHEADER ), &emh );
hDCdesktop=GetDC(hWnd);
PixelsX = (float)GetDeviceCaps( hDCdesktop, LOGPIXELSX );
PixelsY = (float)GetDeviceCaps( hDCdesktop, LOGPIXELSY );
wwidth = (int)((float)(emh.rclFrame.right - emh.rclFrame.left) / (100.0f * 25.4f / PixelsX));
wheight = (int)((float)(emh.rclFrame.bottom - emh.rclFrame.top) / (100.0f * 25.4f / PixelsY));
ReleaseDC(hWnd , hDCdesktop);
GetWindowRect(hWnd, &rect_win);
GetClientRect(hWnd, &rect_cli);
flamewx = (rect_win.right - rect_win.left) - (rect_cli.right - rect_cli.left );
flamewy = (rect_win.bottom - rect_win.top ) - (rect_cli.bottom - rect_cli.top );
MoveWindow(hWnd, rect_win.left , rect_win.top , flamewx + wwidth, flamewy + wheight, 1);
CloseClipboard();
} else {
MessageBox(hWnd,TEXT("クリップボードにEMFがありません"),TEXT("message"),MB_OK);
PostQuitMessage(0);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
PlayEnhMetaFileAtOriginalSize( hdc, hEmf );
EndPaint(hWnd, &ps);
break;
case WM_COMMAND:
switch (LOWORD(wp)) {
case IDM_END:
SendMessage(hWnd, WM_CLOSE, 0, 0);
break;
}
break;
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return (DefWindowProc(hWnd, msg, wp, lp));
}
return 0;
}
// ==========================================================================
/*
FUNCTION : PlayEnhMetaFileAtOriginalSize
Copyright Microsoftです。OpenGL対応は割愛させていただきました。
*/
BOOL PlayEnhMetaFileAtOriginalSize( HDC hDC, HENHMETAFILE hMeta )
{
BOOL bFlag;
ENHMETAHEADER emh;
RECT Rect;
float PixelsX, PixelsY, MMX, MMY;
// Do we have a metafile? If not, consider it drawn!
if( hMeta == NULL )
return TRUE;
// Get the header from the enhanced metafile
ZeroMemory( &emh, sizeof(ENHMETAHEADER) );
emh.nSize = sizeof(ENHMETAHEADER);
if( GetEnhMetaFileHeader( hMeta, sizeof( ENHMETAHEADER ), &emh ) == 0 )
return FALSE;
// Get the characteristics of the output device
PixelsX = (float)GetDeviceCaps( hDC, HORZRES );
PixelsY = (float)GetDeviceCaps( hDC, VERTRES );
MMX = (float)GetDeviceCaps( hDC, HORZSIZE );
MMY = (float)GetDeviceCaps( hDC, VERTSIZE );
// Calculate the rect in which to draw the metafile based on the
// intended size and the current output device resolution
// Remember that the intended size is given in 0.01mm units, so
// convert those to device units on the target device
Rect.top = (int)((float)(emh.rclFrame.top) * PixelsY / (MMY*100.0f));
Rect.left = (int)((float)(emh.rclFrame.left) * PixelsX / (MMX*100.0f));
Rect.right = (int)((float)(emh.rclFrame.right) * PixelsX / (MMX*100.0f));
Rect.bottom = (int)((float)(emh.rclFrame.bottom) * PixelsY / (MMY*100.0f));
// Play the metafile in that rectangle
bFlag = PlayEnhMetaFile( hDC, hMeta, &Rect );
return bFlag;
}
// End PlayEnhMetaFileAtOriginalSize
// ==========================================================================