[ファイル]-[新規作成]-[プロジェクト]-[Win32 Dynamic-Link Library]。
test.h と test.cpp は同じディレクトリに置く。 test.cpp をプロジェクトに追加して[ビルド]する。 DLLファイルとLIBファイルが作成される。 vc は、DEFファイルの方にも対応しているが、bcc は、こちらしか対応していない。 |
// test.h の内容 #include <windows.h> #define DECLSPEC extern "C" __declspec( dllexport ) DECLSPEC void DisplayMessage( LPCTSTR lpszMessage ); // test.cpp の内容 #include "test.h" extern "C" int APIENTRY DllMain( HINSTANCE hInst, DWORD dwReason, LPVOID lpRsv ) { return TRUE; } void DisplayMessage( LPCTSTR lpszMessage ) { MessageBox( NULL, lpszMessage, "DLLTEST", MB_OK ); } |
[ファイル]-[新規作成]-[プロジェクト]-[Win32 Dynamic-Link Library]。
test.h と test.cpp と test.def は同じフォルダに置く。 test.cpp と test.def をプロジェクトに追加して[ビルド]する。 DLLファイルとLIBファイルが作成される。 DEFファイルは、モジュール定義ファイルと呼ぶ。 |
// test.h の内容 #include <windows.h> void DisplayMessage( LPCTSTR lpszMessage ); // test.cpp の内容 #include "test.h" int APIENTRY DllMain( HINSTANCE hInst, DWORD dwReason, LPVOID lpRsv ) { return TRUE; } void DisplayMessage( LPCTSTR lpszMessage ) { MessageBox( NULL, lpszMessage, "DLLTEST", MB_OK ); } // test.def の内容 LIBRARY test.dll EXPORTS DisplayMessage |
暗黙的リンク(LIBファイルとDLLファイルを使用する)の場合。
[ファイル]-[新規作成]-[プロジェクト]-[Win32 Console Application]。 43.DLLの作成[__declspec(dllexport)を使う場合]で作成した test.lib をソースファイルと同じフォルダに、 test.dll を実行ファイルと同じフォルダにコピーする。 |
#include <windows.h> #pragma comment( lib, "test.lib" ) #define DECLSPEC __declspec( dllimport ) DECLSPEC void DisplayMessage( LPCTSTR lpszMessage ); void main() { DisplayMessage( "DLLEXE!!" ); } |
暗黙的リンク(HファイルとLIBファイルとDLLファイルを使用する)の場合。
[ファイル]-[新規作成]-[プロジェクト]-[Win32 Console Application]。 43.DLLの作成[__declspec(dllexport)を使う場合]で作成した test.h と test.lib をソースファイルと同じフォルダに、 test.dll を実行ファイルと同じフォルダにコピーする。 コピーした test.h の #define DECLSPEC extern "C" __declspec(dllexport) は、 DECLSPEC extern "C" __declspec(dllimport) に書き換えておく。 |
// test.h の内容 #include <windows.h> #define DECLSPEC extern "C" __declspec( dllimport ) DECLSPEC void DisplayMessage( LPCTSTR lpszMessage ); // test.cpp の内容 #include "test.h" #pragma comment( lib, "test.lib" ) void main() { DisplayMessage( "DLLEXE!!" ); } |
明示的リンク(DLLファイルのみを使用する)の場合。
読み込むDLLファイル名をプログラム内で変更できる。 [ファイル]-[新規作成]-[プロジェクト]-[Win32 Console Application]。 43.DLLの作成[__declspec(dllexport)を使う場合]、または、 44.DLLの作成[DEFファイルを使う場合]で作成した test.dll を実行ファイルと同じフォルダにコピーする。 |
#include <windows.h> typedef void ( *DISPLAYMESSAGE )( LPCTSTR ); void main() { HINSTANCE hDll; DISPLAYMESSAGE MyDisplayMessage; hDll = LoadLibrary( "test.dll" ); if( hDll != NULL ){ MyDisplayMessage = (DISPLAYMESSAGE)GetProcAddress( hDll, "DisplayMessage" ); if( MyDisplayMessage ) MyDisplayMessage( "DLLEXE!!" ); FreeLibrary( hDll ); } } |
クラスの場合は、__declspec( dllexport ) を記述する位置が異なる。
また、extern "C" は不要である。 読み込み時は、dll_class.h と dll_class.lib をソースファイルと同じフォルダに、 dll_class.dll を実行ファイルと同じフォルダにコピーする。 コピーした dll_class.h の #define DECLSPEC __declspec(dllexport) は、 DECLSPEC __declspec(dllimport) に書き換えておく。 |
// dll_class.h (作成用)の内容 #define DECLSPEC __declspec( dllexport ) class DECLSPEC CMes { public: CMes( char *lpszMessage ); void DisplayMessage(); ~CMes(); private: char *m_str; }; // dll_class.cpp (作成用)の内容 #include <windows.h> #include "dll_class.h" extern "C" int APIENTRY DllMain( HINSTANCE hInst, DWORD dwReason, LPVOID lpRsv ) { return TRUE; } CMes::CMes( char *lpszMessage ) { m_str = lpszMessage; } void CMes::DisplayMessage() { MessageBox( NULL, m_str, "DLLTEST", MB_OK ); } CMes::~CMes() { m_str = NULL; } // dll_class_read.h (読み込み用)の内容 #define DECLSPEC __declspec( dllimport ) class DECLSPEC CMes { public: CMes( char *lpszMessage ); void DisplayMessage(); ~CMes(); private: char *m_str; }; // dll_class_read.cpp (読み込み用)の内容 #include "dll_class_read.h" #pragma comment( lib, "dll_class.lib" ) void main() { CMes cmes( "DLLEXE!!" ); cmes.DisplayMessage(); } |
HBITMAP には、DDB と DIB の 2 種類があり、両者では内部構造が異なるために、使える関数も異なる場合がある。
クリップボードでは、DDB は、CF_BITMAP を、DIB は、CF_DIB を使う。 DIB から DDB への変換は、CreateDIBitmap() を使う。 以下の例では、LoadImage() を使って、DIB の HBITMAP から BITMAPINFO を取得する。 DDB の HBITMAP から BITMAPINFO を作る場合は、別の方法を使う。 OleLoadPicture(), GDI+ などで取得した HBITMAP からも BITMAPINFO を取得できる。 OleLoadPicture() の場合 LPPICTURE pPic->get_Handle((OLE_HANDLE FAR *) &hBmp); GDI+ の場合 Bitmap Bmp.GetHBITMAP(0, &hBmp); で DIB の HBITMAP を取得する。 |
LRESULT CALLBACK ProcWnd(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static BITMAPINFO *pbmi = NULL; static BYTE *pbits = NULL; switch (uMsg) { case WM_CREATE: if(__argc <= 1){ MessageBox(hWnd, "Btimap ファイルの Drag & Drop 専用です", MYWNDTITLE, 0); SendMessage(hWnd, WM_CLOSE, 0, 0); } DIBSECTION Dib; HBITMAP hBmp; int r,bpp,num_colors,size_pbits,size_pbmi,size_mask; hBmp = (HBITMAP) LoadImage(NULL, __argv[1], IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION); if(!hBmp){ MessageBox(hWnd, "Bitmap ファイルを読み込めません", MYWNDTITLE, 0); SendMessage(hWnd, WM_CLOSE, 0, 0); } // ビットマップの情報を取得 r = GetObject(hBmp, sizeof(DIBSECTION), &Dib); if(r != sizeof(DIBSECTION)) return 0; // ビットマップのピクセル値を取得 // Dib.dsBm.bmWidthBytes は、((((Dib.dsBmih.biWidth * bpp) + 31) & ~31) >> 3) で求められる size_pbits = Dib.dsBm.bmWidthBytes * Dib.dsBm.bmHeight; if(pbits) LocalFree(pbits); pbits = (BYTE *) LocalAlloc(LPTR, size_pbits); memcpy(pbits, Dib.dsBm.bmBits, size_pbits); // パレットの色数を計算 bpp = Dib.dsBmih.biBitCount * Dib.dsBmih.biPlanes; // 1ピクセルあたりのビット数 if(Dib.dsBmih.biClrUsed != 0) num_colors = Dib.dsBmih.biClrUsed; else if(bpp <= 8) num_colors = 1 << bpp; else num_colors = 0; // ピクセルフォーマットマスクのサイズを取得 if(Dib.dsBmih.biCompression == BI_BITFIELDS) size_mask = sizeof(DWORD) * 3; else size_mask = 0; // BITMAPINFO 構造体のメモリを確保 size_pbmi = sizeof(BITMAPINFOHEADER) + size_mask + (num_colors * sizeof(RGBQUAD)); if(pbmi) LocalFree(pbmi); pbmi = (BITMAPINFO *) LocalAlloc(LPTR, size_pbmi); // BITMAPINFOHEADER 構造体をコピー pbmi->bmiHeader = Dib.dsBmih; // パレット または、ピクセルフォーマットマスクを取得 if(bpp <= 8){ HDC hMemDC = CreateCompatibleDC(NULL); HBITMAP hBmp_pre = (HBITMAP) SelectObject(hMemDC, hBmp); GetDIBColorTable(hMemDC, 0, num_colors, pbmi->bmiColors); SelectObject(hMemDC, hBmp_pre); DeleteDC(hMemDC); } else if(Dib.dsBmih.biCompression == BI_BITFIELDS){ memcpy(pbmi->bmiColors, Dib.dsBitfields, size_mask); } // ビットマップのハンドルを削除 DeleteObject(hBmp); // 別名で保存する HANDLE hFile; DWORD dwWrite; char *p; p = strrchr(__argv[1], '.'); if(p){ strcpy(p, "_new.bmp"); } else{ strcat(p, "_new.bmp"); } hFile = CreateFile(__argv[1], GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if(hFile == INVALID_HANDLE_VALUE){ SendMessage(hWnd, WM_CLOSE, 0, 0); } // BITMAPFILEHEADER 構造体を設定 BITMAPFILEHEADER bmfh; ZeroMemory(&bmfh, sizeof(BITMAPFILEHEADER)); bmfh.bfType = 0x4d42; bmfh.bfOffBits = sizeof(bmfh) + size_pbmi; bmfh.bfSize = bmfh.bfOffBits + size_pbits; WriteFile(hFile, &bmfh, sizeof(BITMAPFILEHEADER), &dwWrite, NULL); WriteFile(hFile, pbmi, size_pbmi, &dwWrite, NULL); WriteFile(hFile, pbits, size_pbits, &dwWrite, NULL); CloseHandle(hFile); return 0; case WM_PAINT: HDC hDC; PAINTSTRUCT ps; hDC = BeginPaint(hWnd,&ps); // 描画 if(pbmi){ SetDIBitsToDevice(hDC, 0, 0, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight, 0, 0, 0, pbmi->bmiHeader.biHeight, pbits, pbmi, DIB_RGB_COLORS); } EndPaint(hWnd,&ps); return 0; case WM_CLOSE: // メモリを解放 if(pbmi){ LocalFree(pbmi); pbmi = NULL; } if(pbits){ LocalFree(pbits); pbits = NULL; } DestroyWindow(hWnd); PostQuitMessage(0); return 0; default: break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); } |
ドラッグ&ドロップされたアイコンファイルを表示する。
wType が 2 の場合は、カーソルファイルとなる。 その場合は、wPlanes と wBitCount が、 それぞれホットスポットの X 座標と Y 座標になる。 アイコンの場合は、両方とも 0 が望ましいと MSDN のANIFILE.C に書いてある。 PNG フォーマットには対応していない。 PNG アイコンについては Wikipedia ICO 参照 |
// Source code from the MSDN Library (Icons in Win32, ICONS.C) #include <windows.h> #include <stdio.h> #include "resource.h" #define MYWNDCLASS "MYWNDCLASS" #define MYWNDTITLE "icon" #define NUM_MAX 32 // 取り出す画像の最大数 #define WIDTHBYTES(bits) ((((bits) + 31)>>5)<<2) typedef struct { BYTE bWidth; // Width, in pixels, of the image BYTE bHeight; // Height, in pixels, of the image BYTE bColorCount; // Number of colors in image (0 if >=8bpp) BYTE bReserved; // Reserved ( must be 0) WORD wPlanes; // Color Planes WORD wBitCount; // Bits per pixel DWORD dwBytesInRes; // How many bytes in this resource? DWORD dwImageOffset; // Where in the file is this image? } ICONDIRENTRY, *LPICONDIRENTRY; typedef struct { WORD wReserved; // Reserved (must be 0) WORD wType; // Resource Type (1 for icons) WORD wCount; // How many images? ICONDIRENTRY idEntries[NUM_MAX]; // An entry for each image (wCount of 'em) } ICONDIR, *LPICONDIR; typedef struct { LPBYTE pData; // ptr to DIB data LPBITMAPINFO pbmi; // DIB BITMAPINFO LPBYTE pXOR; // DIB bits for XOR mask LPBYTE pAND; // DIB bits for AND mask } ICONIMAGE, *LPICONIMAGE; ICONDIR g_id; // アイコンのファイルヘッダ ICONIMAGE g_iImg[NUM_MAX]; // アイコンのインフォヘッダとピクセルデータ char g_file_name[MAX_PATH]; // 読み込み・保存ファイル名 LRESULT CALLBACK ProcWnd(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); bool DrawANDMask(HDC hDC); void Load_Dialog(HWND hWnd); bool Load_Icon(HWND hWnd); bool AdjustIconImagePointers( LPICONIMAGE pIImg ); LPBYTE FindDIBBits( LPBITMAPINFOHEADER lpbih ); WORD PaletteSize( LPBITMAPINFOHEADER lpbih ); WORD DIBNumColors( LPBITMAPINFOHEADER lpbih ); DWORD BytesPerLine( LPBITMAPINFOHEADER lpBMIH ); void Save_Dialog(HWND hWnd); bool Save_Icon(HWND hWnd); DWORD CalculateImageOffset( UINT nIndex ); void Set_Title(HWND hWnd); void Cleanup(); int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hInstPrev,LPSTR lpCmdLine,int nCmdShow) { MSG msg; WNDCLASSEX wc; HWND hWnd; ZeroMemory(&wc, sizeof(wc)); wc.cbSize = sizeof(WNDCLASSEX); wc.lpfnWndProc = (WNDPROC)ProcWnd; wc.hInstance = hInst; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = NULL; wc.lpszClassName = MYWNDCLASS; RegisterClassEx(&wc); HMENU hMenu = LoadMenu(hInst,MAKEINTRESOURCE(IDR_MENU1)); hWnd = CreateWindowEx(WS_EX_ACCEPTFILES, MYWNDCLASS, MYWNDTITLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 256, 256, NULL, hMenu, hInst, NULL); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; }// WinMain LRESULT CALLBACK ProcWnd(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CREATE: if(__argc > 1){ strncpy(g_file_name, __argv[1], sizeof(g_file_name)); Load_Icon(hWnd); } return 0; case WM_DROPFILES: HDROP hDrop; hDrop = (HDROP) wParam; DragQueryFile(hDrop, 0, g_file_name, sizeof(g_file_name)); Load_Icon(hWnd); DragFinish(hDrop); SetForegroundWindow(hWnd); return 0; case WM_COMMAND: switch( LOWORD(wParam) ) { case IDM_OPEN: // 開く Load_Dialog(hWnd); break; case IDM_SAVEAS:// 名前を付けて保存 Save_Dialog(hWnd); break; case IDM_EXIT: // 終了 Cleanup(); SendMessage(hWnd,WM_CLOSE,0,0); break; } return 0; case WM_PAINT: HDC hDC; PAINTSTRUCT ps; hDC = BeginPaint(hWnd,&ps); DrawANDMask(hDC); EndPaint(hWnd,&ps); return 0; case WM_CLOSE: DestroyWindow(hWnd); PostQuitMessage(0); return 0; default: break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); }// ProcWnd bool DrawANDMask( HDC hDC ) { int i,indent = 0; for(i=0;i<g_id.wCount;i++){ if( g_iImg[i].pData == NULL ){ continue; } if(g_iImg[i].pbmi->bmiHeader.biSize != sizeof(BITMAPINFOHEADER)){ continue; } int height = g_iImg[i].pbmi->bmiHeader.biHeight / 2; SetDIBitsToDevice( hDC, indent, 0, g_iImg[i].pbmi->bmiHeader.biWidth, height, 0, 0, 0, height, g_iImg[i].pXOR, g_iImg[i].pbmi, DIB_RGB_COLORS ); LPBITMAPINFO lpbi; lpbi = (LPBITMAPINFO) malloc( sizeof(BITMAPINFO) + (2 * sizeof( RGBQUAD )) ); lpbi->bmiHeader.biSize = sizeof( BITMAPINFOHEADER ); lpbi->bmiHeader.biWidth = g_iImg[i].pbmi->bmiHeader.biWidth; lpbi->bmiHeader.biHeight = height; lpbi->bmiHeader.biPlanes = 1; lpbi->bmiHeader.biBitCount = 1; lpbi->bmiHeader.biCompression = BI_RGB; lpbi->bmiHeader.biSizeImage = 0; // lpbi->bmiHeader.biSizeImage = WIDTHBYTES(lpbi->bmiHeader.biWidth * // lpbi->bmiHeader.biPlanes * lpbi->bmiHeader.biBitCount) * // lpbi->bmiHeader.biHeight; lpbi->bmiHeader.biXPelsPerMeter = 0; lpbi->bmiHeader.biYPelsPerMeter = 0; lpbi->bmiHeader.biClrUsed = 0; lpbi->bmiHeader.biClrImportant = 0; lpbi->bmiColors[0].rgbRed = 0; lpbi->bmiColors[0].rgbGreen = 0; lpbi->bmiColors[0].rgbBlue = 0; lpbi->bmiColors[0].rgbReserved = 0; lpbi->bmiColors[1].rgbRed = 255; lpbi->bmiColors[1].rgbGreen = 255; lpbi->bmiColors[1].rgbBlue = 255; lpbi->bmiColors[1].rgbReserved = 0; SetDIBitsToDevice( hDC, indent, lpbi->bmiHeader.biHeight, lpbi->bmiHeader.biWidth, lpbi->bmiHeader.biHeight, 0, 0, 0, lpbi->bmiHeader.biHeight, g_iImg[i].pAND, lpbi, DIB_RGB_COLORS ); free( lpbi ); indent += (g_iImg[i].pbmi->bmiHeader.biWidth + 1); } return TRUE; }// DrawANDMask // オープンダイアログ void Load_Dialog(HWND hWnd) { OPENFILENAME ofn; char fn[MAX_PATH]; fn[0] = '\0'; ZeroMemory(&ofn, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hWnd; ofn.Flags = OFN_HIDEREADONLY; ofn.lpstrFile = fn; ofn.nMaxFile = sizeof(fn); ofn.lpstrFilter = "アイコン ファイル (*.ico)\0" "*.ico\0" "すべてのファイル (*.*)\0" "*.*\0"; ofn.nFilterIndex = 1; if (GetOpenFileName(&ofn)){ strcpy(g_file_name,fn); if(ofn.nFilterIndex == 1){ if(strrchr(g_file_name,'.') == NULL){ strcat(g_file_name,".ico"); } } Load_Icon(hWnd); } }// Load_Dialog // ファイルからデータを読み込む bool Load_Icon(HWND hWnd) { HANDLE hFile; DWORD dwRead; Cleanup(); Set_Title(hWnd); hFile = CreateFile(g_file_name,GENERIC_READ,FILE_SHARE_READ, NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(hFile == INVALID_HANDLE_VALUE){ return 0; } // Read the Reserved word ReadFile( hFile, &(g_id.wReserved), sizeof( WORD ), &dwRead, NULL ); // Read the Type word - make sure it is 1 for icons ReadFile( hFile, &(g_id.wType), sizeof( WORD ), &dwRead, NULL ); if(g_id.wType != 1) return 0; // Read the count - how many images in this file? ReadFile( hFile, &(g_id.wCount), sizeof( WORD ), &dwRead, NULL ); g_id.wCount = NUM_MAX > g_id.wCount ? g_id.wCount : NUM_MAX; // Read the ICONDIRENTRY elements ReadFile( hFile, g_id.idEntries, g_id.wCount * sizeof(ICONDIRENTRY), &dwRead, NULL ); // Loop through and read in each image for(int i=0;i<g_id.wCount;i++) { if(i >= NUM_MAX) break; // Allocate memory to hold the image g_iImg[i].pData = new BYTE [g_id.idEntries[i].dwBytesInRes]; // Seek to the location in the file that has the image SetFilePointer( hFile, g_id.idEntries[i].dwImageOffset, NULL, FILE_BEGIN ); // Read the image data ReadFile( hFile, g_iImg[i].pData, g_id.idEntries[i].dwBytesInRes, &dwRead, NULL ); // Set the internal pointers appropriately AdjustIconImagePointers( &(g_iImg[i]) ); } CloseHandle(hFile); InvalidateRect(hWnd,NULL,TRUE); return 1; }// Load_Icon bool AdjustIconImagePointers( LPICONIMAGE pIImg ) { // Sanity check if( pIImg == NULL ) return false; // BITMAPINFO is at beginning of bits pIImg->pbmi = (LPBITMAPINFO) pIImg->pData; // XOR bits follow the header and color table pIImg->pXOR = FindDIBBits(&(pIImg->pbmi->bmiHeader)); // AND bits follow the XOR bits pIImg->pAND = pIImg->pXOR + (pIImg->pbmi->bmiHeader.biHeight / 2 * BytesPerLine((LPBITMAPINFOHEADER)&(pIImg->pbmi->bmiHeader))); return true; }// AdjustIconImagePointers LPBYTE FindDIBBits( LPBITMAPINFOHEADER lpbih ) { return (LPBYTE) lpbih + *(LPDWORD)lpbih + PaletteSize( lpbih ); }// FindDIBBits WORD PaletteSize( LPBITMAPINFOHEADER lpbih ) { return ( DIBNumColors( lpbih ) * sizeof( RGBQUAD ) ); }// PaletteSize WORD DIBNumColors( LPBITMAPINFOHEADER lpbih ) { int num; if(lpbih->biBitCount > 8) num = 0; else if(lpbih->biClrUsed == 0) num = 1 << lpbih->biBitCount; else num = lpbih->biClrUsed; return num; }// DIBNumColors DWORD BytesPerLine( LPBITMAPINFOHEADER lpBMIH ) { return WIDTHBYTES(lpBMIH->biWidth * lpBMIH->biPlanes * lpBMIH->biBitCount); }// BytesPerLine // セーブダイアログ void Save_Dialog(HWND hWnd) { OPENFILENAME ofn; char fn[MAX_PATH]; fn[0] = '\0'; ZeroMemory(&ofn, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = hWnd; ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_EXTENSIONDIFFERENT; ofn.lpstrFile = fn; ofn.nMaxFile = sizeof(fn); ofn.lpstrDefExt = "ico"; ofn.lpstrFilter = "アイコン ファイル (*.ico)\0" "*.ico\0" "すべてのファイル (*.*)\0" "*.*\0"; ofn.nFilterIndex = 1; if (GetSaveFileName(&ofn)){ strcpy(g_file_name,fn); Save_Icon(hWnd); } }// Save_Dialog // ファイルにデータを書き込む bool Save_Icon(HWND hWnd) { HANDLE hFile; DWORD dwWrite; int i; Set_Title(hWnd); // open the file hFile = CreateFile(g_file_name,GENERIC_WRITE,FILE_SHARE_WRITE, NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); if(hFile == INVALID_HANDLE_VALUE){ return 0; } // Write the Reserved word WriteFile( hFile, &(g_id.wReserved), sizeof( WORD ), &dwWrite, NULL ); // Write the Type word - make sure it is 1 for icons WriteFile( hFile, &(g_id.wType), sizeof( WORD ), &dwWrite, NULL ); // Write the count - how many images in this file? int num; NUM_MAX > g_id.wCount ? num = g_id.wCount : num = NUM_MAX; WriteFile( hFile, &num, sizeof( WORD ), &dwWrite, NULL ); for(i=0;i<num;i++) { ICONDIRENTRY ide; // Convert internal format to ICONDIRENTRY ide.bWidth = (BYTE) g_iImg[i].pbmi->bmiHeader.biWidth; ide.bHeight = (BYTE) g_iImg[i].pbmi->bmiHeader.biHeight / 2; ide.bReserved = 0; ide.wPlanes = 0; ide.wBitCount = 0; UINT bpp = g_iImg[i].pbmi->bmiHeader.biPlanes * g_iImg[i].pbmi->bmiHeader.biBitCount; if( bpp >= 8 ) ide.bColorCount = 0; else ide.bColorCount = 1 << bpp; ide.dwBytesInRes = g_id.idEntries[i].dwBytesInRes; ide.dwImageOffset = CalculateImageOffset( i ); // Write the ICONDIRENTRY out to disk WriteFile( hFile, &ide, sizeof( ICONDIRENTRY ), &dwWrite, NULL ); // Did we write a full ICONDIRENTRY ? if( dwWrite != sizeof( ICONDIRENTRY ) ) return 0; } for(i=0;i<num;i++) { DWORD dwTemp = g_iImg[i].pbmi->bmiHeader.biSizeImage; // Set the sizeimage member to zero g_iImg[i].pbmi->bmiHeader.biSizeImage = 0; // Write the image data to file WriteFile( hFile, g_iImg[i].pData, g_id.idEntries[i].dwBytesInRes, &dwWrite, NULL ); if( dwWrite != g_id.idEntries[i].dwBytesInRes ) return 0; // set it back g_iImg[i].pbmi->bmiHeader.biSizeImage = dwTemp; } CloseHandle(hFile); return 1; }// Save_Icon DWORD CalculateImageOffset( UINT nIndex ) { DWORD dwSize; UINT i; // Calculate the ICO header size dwSize = 3 * sizeof(WORD); // Add the ICONDIRENTRY's dwSize += g_id.wCount * sizeof(ICONDIRENTRY); // Add the sizes of the previous images for(i=0;i<nIndex;i++) dwSize += g_id.idEntries[i].dwBytesInRes; // we're there - return the number return dwSize; }// CalculateImageOffset // ウィンドウタイトルの変更 void Set_Title(HWND hWnd) { char *p,s[MAX_PATH]; p = strrchr(g_file_name,'\\'); sprintf(s,"%s <%s>",MYWNDTITLE,p+1); SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)s); }// Set_Title // メモリの解放 void Cleanup() { for(int i=0;i<NUM_MAX;i++){ delete [] (g_iImg[i].pData); g_iImg[i].pData = NULL; } }// Cleanup |
ファイルのショートカットをデスクトップに作成する。
|
// Source code from the MSDN Library (Using Shell Links in Windows 95) #include <windows.h> #include <stdio.h> #include <shlobj.h> #define MYWNDTITLE "shortcut" HRESULT CreateShortCut(LPCSTR pszShortcutFile, LPSTR pszLink, LPSTR pszDesc) { HRESULT hres; IShellLink* psl; // Get a pointer to the IShellLink interface. hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void **) &psl); if (SUCCEEDED(hres)) { IPersistFile* ppf; // Query IShellLink for the IPersistFile interface for // saving the shell link in persistent storage. hres = psl->QueryInterface(IID_IPersistFile, (void **) &ppf); if (SUCCEEDED(hres)) { WORD wsz[MAX_PATH]; // Set the path to the shell link target. hres = psl->SetPath(pszShortcutFile); if (!SUCCEEDED(hres)) MessageBox(0, "SetPath failed!", MYWNDTITLE, 0); // Set the description of the shell link. hres = psl->SetDescription(pszDesc); if (!SUCCEEDED(hres)) MessageBox(0, "SetDescription failed!", MYWNDTITLE, 0); // Ensure string is ANSI. MultiByteToWideChar(CP_ACP, 0, pszLink, -1, wsz, MAX_PATH); // Save the link via the IPersistFile::Save method. hres = ppf->Save(wsz, TRUE); // Release pointer to IPersistFile. ppf->Release(); } // Release pointer to IShellLink. psl->Release(); } return hres; }// CreateShortCut int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hInstPrev,LPSTR lpCmdLine,int nCmdShow) { if(__argc <= 1){ MessageBox(0, "Drag & Drop 専用です", MYWNDTITLE, 0); return 0; } CoInitialize(NULL); char desktop_path[MAX_PATH]; char file_name[MAX_PATH]; char shortcut_name[MAX_PATH]; char shortcut_desc[MAX_PATH]; char *p; SHGetSpecialFolderPath(NULL, desktop_path, CSIDL_DESKTOPDIRECTORY, FALSE); strncpy(file_name, __argv[1], MAX_PATH); GetFileTitle(file_name, shortcut_desc, MAX_PATH); p = strrchr(shortcut_desc, '.'); if(p) strcpy(p, "のショートカット"); _snprintf(shortcut_name, MAX_PATH,"%s\\%s.lnk", desktop_path, shortcut_desc); strcat(shortcut_desc, "のコメント"); if(GetFileAttributes(shortcut_name) == -1) CreateShortCut(file_name, shortcut_name, shortcut_desc); else MessageBox(0, "デスクトップに同名のショートッカットが存在しています", MYWNDTITLE, 0); CoUninitialize(); return 0; }// WinMain |
GDI+ の場合は、ファイル名に WMF と EMF を指定できる。
GDI の場合は、EMF ファイルのみ指定できる。 WMF ファイルを表示したいときは、フォーマットを EMF に変換する必要がある。 |
////////////////// GDI の場合 ////////////////// HENHMETAFILE hEmf = GetEnhMetaFile("sample.emf"); ENHMETAHEADER emh; HDC hDC = GetDC(hWnd); GetEnhMetaFileHeader(hEmf, sizeof(emh), &emh); PlayEnhMetaFile(hDC, hEmf, (RECT*)&emh.rclBounds); DeleteEnhMetaFile(hEmf); ReleaseDC(hWnd, hDC); ////////////////// GDI+ の場合 ///////////////// Metafile meta(L"sample.emf"); HDC hDC = GetDC(hWnd); Graphics g(hDC); g.DrawImage(&meta, Rect(0, 0, meta.GetWidth(), meta.GetHeight())); ReleaseDC(hWnd, hDC); |
|
// フルパスからファイル名(Windows7 以前は拡張子なし。Windows7 は拡張子あり)を抜き出す char path[MAX_PATH],title[MAX_PATH]; GetFileTitle(path, title, sizeof(title)); // カレントドライブの取得 char drive[MAX_PATH]; GetCurrentDirectory(sizeof(drive), drive); char *p = strchr(drive, '\\'); if(p){ strcpy(p+1, ""); } // フルパスの分解 char full_path[_MAX_PATH]; // フルパス名 char drive[_MAX_DRIVE]; // ドライブ名 char dir[_MAX_DIR]; // ディレクトリー パス char fname[_MAX_FNAME]; // ファイル名 char ext[_MAX_EXT]; // 拡張子 _splitpath(full_path, drive, dir, fname, ext); |
case WM_DROPFILES: // SetForegroundWindow関数を使う(hWnd はメインウィンドウのハンドル) SetForegroundWindow(hWnd); // または、mouse_event関数を使う mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0); mouse_event(MOUSEEVENTF_LEFTUP, 0,0,0,0); break; |
STDREG32.MDB を例えば、C ドライブ直下にコピーして、
[コントロールパネル]→[ODBC データソース]→[ユーザDSN]タブ→[追加] →[Microsoft Access Driver(*.mdb)]→[完了]→[データソース名]に、 Student Registration と入力→[選択]で STDREG32.MDB を選択→[OK] → [詳細設定]でユーザ名、パスワードを設定→[OK]→[OK] をあらかじめ実行する。 または、SQLConfigDataSource()を使用する。 データベース名は、データソース名のこと。 以下の例では、ユーザ名とパスワードは未設定。 STDREG32.MDB は、MSDN Library CD 内のサンプル ファイル。 Student Registration には、COURSE, STUDENT, INSTRUCTOR, SECTION, DYNABIND_SECTION, ENROLLMENT の6つのテーブルが入っている。 Win98, Me, 2000, Xp 専用 |
#include <windows.h> #include <sql.h> #include <sqlext.h> #define MYWNDCLASS "ODBC_CLASS" #define MYWNDTITLE "ODBC" #define MAXBUFLEN 256 // string buffer size #define MAX_COL 15 // maximum column in result set #define MAX_ROW 100 // maximum number of rows #define MAXDATALEN 25 // maximum data length per column #define NULLDATASTRING "SQL_NULL_DATA" // NULLレコードの置き換え文字列 SQLHENV g_hEnv = NULL; // Environment Handle SQLHDBC g_hDbc = NULL; // hdbc int g_nRows = 0; // データの数 char g_sDispBuffer[MAX_ROW][MAX_COL*(MAXDATALEN+1)]; // 読み込んだデータ(全部) LRESULT CALLBACK ProcWnd(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); bool InitEnv(); bool ConnectDB(SQLCHAR *sDsn, SQLCHAR *sUser, SQLCHAR *sPass); bool DriverConnectDB(HWND hWnd); void ExecuteQuery(SQLCHAR *sSqlStatement); void CloseDB(); void FreeEnv(); LRESULT CALLBACK ProcWnd(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CREATE: { InitEnv(); // ConnectDB か DriverConnectDB のどちらかを実行する bool flag = true; if(flag){ ConnectDB((SQLCHAR*)"Student Registration", (SQLCHAR*)"", (SQLCHAR*)""); } else{ DriverConnectDB(hWnd); } ExecuteQuery((SQLCHAR*)"SELECT * FROM STUDENT"); } return 0; case WM_PAINT: HDC hDC; PAINTSTRUCT ps; hDC = BeginPaint(hWnd,&ps); RECT rc; int i; for(i=0;i<g_nRows;i++){ SetRect(&rc,0,i*20,1000,(i+1)*20); DrawText(hDC, g_sDispBuffer[i], strlen(g_sDispBuffer[i]), &rc, DT_EXPANDTABS | DT_TABSTOP | (18 << 8)); } EndPaint(hWnd,&ps); return 0; case WM_CLOSE: FreeEnv(); DestroyWindow(hWnd); PostQuitMessage(0); return 0; default: break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); }// ProcWnd // 初期化 bool InitEnv() { if(SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &g_hEnv) != SQL_SUCCESS) return false; if(SQLSetEnvAttr(g_hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER) != SQL_SUCCESS) return false; return true; }// InitEnv // データベース名、ユーザ名、パスワードを指定してデータベースに接続する bool ConnectDB(SQLCHAR *sDsn, SQLCHAR *sUser, SQLCHAR *sPass) { SQLRETURN nResult; // Result code if(SQLAllocHandle(SQL_HANDLE_DBC, g_hEnv, (SQLHDBC FAR *)&g_hDbc) != SQL_SUCCESS){ return false; } nResult = SQLConnect(g_hDbc, sDsn, SQL_NTS, sUser, SQL_NTS, sPass, SQL_NTS); if(nResult != SQL_SUCCESS && nResult != SQL_SUCCESS_WITH_INFO){ SQLFreeHandle(SQL_HANDLE_DBC, g_hDbc); return false; } return true; }// ConnectDB // データベース選択ダイアログを使ってデータベースに接続する bool DriverConnectDB(HWND hWnd) { SQLCHAR sBuffer[MAXBUFLEN+1]; //display successful connection info on hdbc(s) combo-box SWORD swStrLen; //String length SQLRETURN nResult; //result code if(SQLAllocHandle(SQL_HANDLE_DBC, g_hEnv, (SQLHDBC FAR *)&g_hDbc) != SQL_SUCCESS){ return false; } nResult = SQLDriverConnect(g_hDbc, hWnd, (SQLCHAR*)"", 0, sBuffer, MAXBUFLEN, &swStrLen, SQL_DRIVER_COMPLETE_REQUIRED); if(nResult != SQL_SUCCESS && nResult != SQL_SUCCESS_WITH_INFO){ SQLFreeHandle(SQL_HANDLE_DBC, g_hDbc); return false; } return true; }// DriverConnectDB // SQLステートメントを実行する void ExecuteQuery(SQLCHAR *sSqlStatement) { SQLHSTMT hstmt; SQLSMALLINT nCols = 0; // フィールドの数 SQLSMALLINT iColType; // フィールドの型(SQL_CHAR, SQL_INTEGER ...) SQLSMALLINT iColNull; // このフィールドのレコードにNULLは入力可能か? SQLSMALLINT iColScale; // フィールドのサイズ(決まってなかったら 0) SQLUINTEGER uiColDef; // 正確な10進数 SQLSMALLINT iColLen; // フィールド名の実際の長さ SQLCHAR sBuffer[MAXDATALEN+1]; // フィールド名 int i; SQLCHAR sData[MAX_COL][MAXDATALEN]; // Results Data Array(1レコード分) SQLINTEGER iDataLen[MAX_COL]; // Results Data Length Array(1レコード分) if(SQLAllocHandle(SQL_HANDLE_STMT,g_hDbc, &hstmt) != SQL_SUCCESS){ return; } // SQLステートメントを実行 SQLExecDirect(hstmt, sSqlStatement, SQL_NTS); // フィールド数を取得 SQLNumResultCols(hstmt, &nCols); if(nCols >= MAX_COL) nCols = MAX_COL; if(!nCols) return; g_sDispBuffer[0][0] = '\0'; // フィールド名を取得 for(i=1; i<= nCols; i++){ SQLDescribeCol(hstmt, i, sBuffer, MAXDATALEN, &iColLen, &iColType, &uiColDef, &iColScale, &iColNull); strcat(g_sDispBuffer[0], (char*)sBuffer); strcat(g_sDispBuffer[0], "\t"); } g_sDispBuffer[0][strlen(g_sDispBuffer[0])-1] = '\0'; // レコードを配列にバインド for(i=0; i<nCols; i++){ SQLBindCol(hstmt, (UWORD)(i+1), SQL_C_CHAR, sData[i], MAXDATALEN, &iDataLen[i]); } // レコードを取得 g_nRows = 1; while(SQLFetch(hstmt) == SQL_SUCCESS){ for(i=0; i<nCols; i++){ // check if the column is a null value? strcat(g_sDispBuffer[g_nRows], (iDataLen[i]==SQL_NULL_DATA)?NULLDATASTRING:(char*)sData[i]); strcat(g_sDispBuffer[g_nRows], "\t"); } g_sDispBuffer[g_nRows][strlen(g_sDispBuffer[g_nRows])-1] = '\0'; g_nRows ++; if(g_nRows >= MAX_ROW){ g_nRows = MAX_ROW - 1; break; } } // カーソルを閉じる SQLCloseCursor(hstmt); // バインドを解除 SQLFreeStmt(hstmt, SQL_UNBIND); // ハンドルを解放 SQLFreeHandle(SQL_HANDLE_STMT, hstmt); }// ExecuteQuery // データベースの接続を切る void CloseDB() { SQLDisconnect(g_hDbc); SQLFreeHandle(SQL_HANDLE_DBC, g_hDbc); }// CloseDB // 終了処理 void FreeEnv() { CloseDB(); SQLFreeHandle(SQL_HANDLE_ENV, g_hEnv); }// FreeEnv |
データベースとテーブルを作成して、レコードを追加する
[コントロールパネル]→[ODBC データソース]→[ドライバ]タブで、Access odbc driver (odbcjt32.dll) がインストールされていることをあらかじめ確認すること Win98, Me, 2000, Xp 専用 odbccp32.lib のリンク設定が必要 |
#include <windows.h> #include <stdio.h> #include <sql.h> #include <sqlext.h> #include <odbcinst.h> #define MYWNDCLASS "ODBC_Create_CLASS" #define MYWNDTITLE "ODBC_Create" #define DSN "新規データソース" #define DESC "ODBC データベース作成サンプル" #define USERID "user" #define PASSWORD "password" #define FILENAME "C:\\new.mdb" SQLHENV g_hEnv = NULL; // Environment Handle SQLHDBC g_hDbc = NULL; // hdbc LRESULT CALLBACK ProcWnd(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); bool CreateMDB(HWND hWnd, char *sDsn, char *sDesc, char *sUser, char *sPass, char *sFile); bool InitEnv(); bool ConnectDB(SQLCHAR *sDsn, SQLCHAR *sUser, SQLCHAR *sPass); void ExecuteQuery(SQLCHAR *sSqlStatement); void CloseDB(); void FreeEnv(); LRESULT CALLBACK ProcWnd(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CREATE: CreateMDB(hWnd,DSN,DESC,USERID,PASSWORD,FILENAME); InitEnv(); ConnectDB((SQLCHAR*)DSN, (SQLCHAR*)USERID, (SQLCHAR*)PASSWORD); // テーブル foo を作成 ExecuteQuery((SQLCHAR*)"CREATE TABLE foo (a INTEGER, b VARCHAR(20))"); // テーブル foo にレコードを追加 ExecuteQuery((SQLCHAR*)"INSERT INTO foo VALUES(100, 'abc')"); ExecuteQuery((SQLCHAR*)"INSERT INTO foo VALUES(222, 'fff')"); ExecuteQuery((SQLCHAR*)"INSERT INTO foo VALUES(0, '')"); MessageBox(hWnd, "処理終了", MYWNDTITLE, MB_OK); return 0; case WM_CLOSE: FreeEnv(); DestroyWindow(hWnd); PostQuitMessage(0); return 0; default: break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); }// ProcWnd // MDBファイルを新規作成して、ODBCデータソースに格納する bool CreateMDB(HWND hWnd, char *sDsn, char *sDesc, char *sUser, char *sPass, char *sFile) { WORD fRequest = ODBC_ADD_DSN; char sDriver[] = "Microsoft Access Driver (*.mdb)"; char sAttributes1[256],sAttributes2[256]; _snprintf(sAttributes1, sizeof(sAttributes1), "CREATE_DB=%s General;", sFile); if(!SQLConfigDataSource(NULL, fRequest, sDriver, sAttributes1)){ MessageBox(hWnd,"MDBファイルを作成できません",MYWNDTITLE,MB_OK); return false; } _snprintf(sAttributes2, sizeof(sAttributes2), "DSN=%s;DESCRIPTION=%s;UID=%s;PWD=%s;DBQ=%s;", sDsn, sDesc, sUser, sPass, sFile); if(!SQLConfigDataSource(hWnd, fRequest, sDriver, sAttributes2)){ MessageBox(hWnd,"データソースに格納できません",MYWNDTITLE,MB_OK); return false; } return true; }// CreateMDB // 初期化 bool InitEnv() { if(SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &g_hEnv) != SQL_SUCCESS) return false; if(SQLSetEnvAttr(g_hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_INTEGER) != SQL_SUCCESS) return false; return true; }// InitEnv // データベース名、ユーザ名、パスワードを指定してデータベースに接続する bool ConnectDB(SQLCHAR *sDsn, SQLCHAR *sUser, SQLCHAR *sPass) { SQLRETURN nResult; // Result code if(SQLAllocHandle(SQL_HANDLE_DBC, g_hEnv, (SQLHDBC FAR *)&g_hDbc) != SQL_SUCCESS){ return false; } nResult = SQLConnect(g_hDbc, sDsn, SQL_NTS, sUser, SQL_NTS, sPass, SQL_NTS); if(nResult != SQL_SUCCESS && nResult != SQL_SUCCESS_WITH_INFO){ SQLFreeHandle(SQL_HANDLE_DBC, g_hDbc); return false; } return true; }// ConnectDB // SQLステートメントを実行する void ExecuteQuery(SQLCHAR *sSqlStatement) { SQLHSTMT hstmt; if(SQLAllocHandle(SQL_HANDLE_STMT,g_hDbc, &hstmt) != SQL_SUCCESS){ return; } // SQLステートメントを実行 SQLExecDirect(hstmt, sSqlStatement, SQL_NTS); // ハンドルを解放 SQLFreeHandle(SQL_HANDLE_STMT, hstmt); }// ExecuteQuery // データベースの接続を切る void CloseDB() { SQLDisconnect(g_hDbc); SQLFreeHandle(SQL_HANDLE_DBC, g_hDbc); }// CloseDB // 終了処理 void FreeEnv() { CloseDB(); SQLFreeHandle(SQL_HANDLE_ENV, g_hEnv); }// FreeEnv |
ODBC 関数でデータベース読み込みと同じ設定を行う。
既に設定済みの場合は、必要なし。 ソースファイルは、cpp ファイルで、プロジェクトは、コンソールで作成する。 Win98, Me, 2000, Xp 専用。 SQL ステートメントには、GradYear も表示するように指示しているが、表示されないコードになっている。 |
#define INITGUID #import "C:\Program Files\Common Files\System\ado\msado15.dll" \ no_namespace rename("EOF", "EndOfFile") \ exclude("RecordCreateOptionsEnum") #include <stdio.h> #include <icrsint.h> void dump_com_error(_com_error &e) { printf("Error\n"); printf("\a\tCode = %08lx\n", e.Error()); printf("\a\tCode meaning = %s", e.ErrorMessage()); _bstr_t bstrSource(e.Source()); _bstr_t bstrDescription(e.Description()); printf("\a\tSource = %s\n", (LPCSTR) bstrSource); printf("\a\tDescription = %s\n", (LPCSTR) bstrDescription); } class CCustomRs : public CADORecordBinding { BEGIN_ADO_BINDING(CCustomRs) ADO_VARIABLE_LENGTH_ENTRY2(1, adVarChar, m_szau_lname, sizeof(m_szau_lname), lau_lnameStatus, FALSE) ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_szau_fname, sizeof(m_szau_fname), lau_fnameStatus, TRUE) END_ADO_BINDING() public: CHAR m_szau_lname[41]; ULONG lau_lnameStatus; CHAR m_szau_fname[41]; ULONG lau_fnameStatus; }; VOID main() { HRESULT hr; IADORecordBinding *picRs = NULL; ::CoInitialize(NULL); try { _RecordsetPtr pRs; CCustomRs rs; pRs.CreateInstance(__uuidof(Recordset)); pRs->Open("select StudentID, Name, GradYear from STUDENT", "dsn=Student Registration;uid=;pwd=;", adOpenStatic, adLockOptimistic, adCmdUnknown); if (FAILED(hr = pRs->QueryInterface(__uuidof(IADORecordBinding), (LPVOID*)&picRs))) _com_issue_error(hr); if (FAILED(hr = picRs->BindToRecordset(&rs))) _com_issue_error(hr); while (VARIANT_FALSE == pRs->EndOfFile) { // Process data in the CCustomRs C++ instance variables. printf("\a\tName = %s \t%s\n", (rs.lau_fnameStatus == adFldOK ? rs.m_szau_fname : "<NULL>"), (rs.lau_lnameStatus == adFldOK ? rs.m_szau_lname : "<NULL>")); // Change the current row of the Recordset. // Recordset data for the new current row will automatically be // extracted and placed in the CCustomRs C++ instance variables. pRs->MoveNext(); } } catch (_com_error &e) { dump_com_error(e); } if (picRs) picRs->Release(); CoUninitialize(); }; |
|
int width = GetSystemMetrics(SM_CXSCREEN); int height = GetSystemMetrics(SM_CYSCREEN); // デスクトップのハンドルが欲しい場合は以下のような方法もある HWND hDsktp = GetDesktopWindow(); RECT rcDsktp; GetClientRect(hDsktp, &rcDsktp); |
クリップボードにあるファイル名をテキストファイルに保存する。
予め、ファイルやフォルダをコピーしてから、プログラムを実行する。 クリップボードにファイル名を置く場合は、実行前にCドライブに 1.txt と 2.txt を作成しておく。 |
#include <windows.h> #include <stdio.h> #include <shlobj.h> // クリップボードからファイル名を取り出す void Get_ClipBoard_HDROP() { HANDLE hMem = NULL; LPDROPFILES pDF = NULL; if(!OpenClipboard(NULL)){ MessageBox(NULL,"クリップボードを開けません",MYWNDTITLE,MB_OK | MB_ICONWARNING); return; } hMem = (HANDLE) GetClipboardData (CF_HDROP); if(!hMem){ MessageBox(NULL,"HDROP がありません",MYWNDTITLE,MB_OK | MB_ICONWARNING); return; } if(GlobalSize(hMem) <= sizeof(DROPFILES)){ return; } pDF = (LPDROPFILES) GlobalLock (hMem); if(!pDF){ MessageBox(NULL,"ロックできません",MYWNDTITLE,MB_OK | MB_ICONWARNING); return; } DWORD offset = pDF->pFiles; POINT pt = pDF->pt; BOOL bNonClientArea = pDF->fNC; BOOL bUnicde = pDF->fWide; DWORD offset2 = 0; FILE *file; if((file=fopen("DROPFILES.txt","w"))==NULL){ MessageBox(NULL,"ファイルを開けません",MYWNDTITLE,MB_OK | MB_ICONWARNING); return; } fprintf(file,"offset:%d\nX:%d Y:%d\nbNonClientArea:%d\nbUnicde:%d\n" ,offset,pt.x,pt.y,bNonClientArea,bUnicde); char *pBuf = (char*) pDF + offset; if(!bUnicde){ while(pBuf[offset2] != '\0'){ fputs(pBuf + offset2,file); offset2 += (strlen(pBuf + offset2) + 1); fputc('\n',file); } } else{ WCHAR *pBufW = (WCHAR*) pBuf; char filename[MAX_PATH]; while(pBufW[offset2] != L'\0'){ WideCharToMultiByte(CP_ACP, 0, pBufW + offset2, -1, filename, sizeof(filename), NULL, NULL); fputs(filename ,file); offset2 += (wcslen(pBufW + offset2) + 1); fputc('\n',file); } } fclose(file); GlobalUnlock(pDF); CloseClipboard(); }// Get_ClipBoard_HDROP // クリップボードにファイル名を置く void Set_ClipBoard_HDROP() { HANDLE hMem = NULL; DROPFILES df; LPBYTE pBuf = NULL; char filename[2][MAX_PATH] = {"C:\\1.txt","C:\\2.txt"}; ZeroMemory(&df, sizeof(df)); df.pFiles = sizeof(df); df.fWide = 0; if(GetFileAttributes(filename[0]) == -1){ MessageBox(NULL,filename[0],"ファイルがありません",MB_OK | MB_ICONWARNING); return; } if(GetFileAttributes(filename[1]) == -1){ MessageBox(NULL,filename[1],"ファイルがありません",MB_OK | MB_ICONWARNING); return; } if(OpenClipboard(NULL)){ EmptyClipboard(); int i,size; size = sizeof(df) + 1; for(i=0;i<2;i++){ size += (strlen(filename[i]) + 1); } hMem = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, size); pBuf = (LPBYTE) GlobalLock(hMem); memcpy(pBuf, &df, sizeof(df)); int offset = sizeof(df); for(i=0;i<2;i++){ memcpy(pBuf + offset, filename[i], strlen(filename[i]) + 1); offset += (strlen(filename[i]) + 1); } memcpy(pBuf + offset, "", 1); SetClipboardData(CF_HDROP, hMem); GlobalUnlock(hMem); CloseClipboard(); } }// Set_ClipBoard_HDROP int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hInstPrev,LPSTR lpCmdLine,int nCmdShow) { Get_ClipBoard_HDROP(); return 0; }// WinMain |
|
// 指定されたフォルダを開く ShellExecute(hWnd, NULL, "C:\\WINDOWS", NULL, NULL, SW_SHOWNORMAL); または ShellExecute(hWnd, "explore", "C:\\WINDOWS", NULL, NULL, SW_SHOWNORMAL); // 指定されたファイルを検索する SearchPath( LPCTSTR lpPath, // [in] 検索したいフォルダのパス名へのポインタ、またはNULL LPCTSTR lpFileName, // [in] ファイル名へのポインタ LPCTSTR lpExtension, // [in] 拡張子へのポインタ(lpFileNameに拡張子がある場合はNULL。先頭に.を付ける) DWORD nBufferLength, // [in] lpBufferのサイズ LPTSTR lpBuffer, // [out] バッファへのポインタ(パスとファイル名が格納されるバッファ) LPTSTR *lpFilePart // [out] lpBuffer内のファイル名へのポインタを格納する変数へのポインタ ) |
ポップアップメニューのマウスキャプチャーを解除したい時は、
SetCapture() を先ず実行する SetCapture(hWnd); ReleaseCapture(); |
|
|
#define PWM_1 WM_APP+1 HWND g_hChild = NULL; int CALLBACK ProcWnd() { switch (uMsg) { case WM_INITDIALOG: SendMessage(g_hChild,PWM_1,0,0); return 0; } return DefWindowProc(); } int CALLBACK ProcChild() { switch (uMsg) { case PWM_1: return 0; } return DefWindowProc(); } |
キーが、押されっぱなしの状態のときは、処理したくない場合
|
LRESULT CALLBACK ProcWnd(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_KEYDOWN: if(!(lParam & 0x40000000)){ // リピートではない場合 switch (wParam) { case VK_RETURN: // Enterキー return 0; } } break; } return DefWindowProc(hWnd, uMsg, wParam, lParam); } |
[ LINK : warning LNK4089: "???.dll" へのすべての参照は /OPT:REF によって廃棄されます ] 作っただけで呼び出されない関数がある場合に、表示されることがある。 [ Link Error LNK1104: Cannot Open File OLECLI32.LIB ] MSDEV.EXE のリンクの設定を OLECLI32.LIB → ole32.lib OLESVR32.LIB → oleaut32.lib に変更する。 [ Runtime Error! R6002 -floating point not loaded ] scanf() や sscanf() で取得した浮動小数点数が、どこにも使われてない場合に発生するエラー char str1[] = "1.2 3.4 5.6 7.8"; float f1,f2,f3; sscanf(str1, "%f %f %f", &f1, &f2, &f3); これを以下のように変更する float f1,f2,f3,f4,f5,f6; sscanf(str1, "%f %f %f", &f4, &f5, &f6); f1 = f4; f2 = f5; f3 = f6; |