AddressPrint
Visual C++ 2005 Express Edition
Windows Server 2003 SP1 Platform SDK
Windowsアプリケーション / 空のプロジェクト
郵便番号枠
sample.csv
郵便番号,住所1,住所2,住所3,名前1,名前2 012-3456,○○県○○市,○○1―1,○○アパート×××号室,○○ ○○, ○ 123-4567,○○県○○市,○○1―1,,○ ○,
AddressPrint.c
// マルチバイト文字セット // comctl32.lib #pragma warning(disable:4996) #include
#include
#include
#define APPNAME "AddressPrint" #define VIEWNAME "View" #define BUFFER_SIZE 256 #define IDC_WND_STATUS 1 #define IDC_WND_VIEW 2 #define IDC_EDT_LINE 3 #define IDC_BTN_DEC 4 #define IDC_BTN_INC 5 #define IDC_BTN_PRINT 6 // グローバル変数 static HINSTANCE g_hInstance; static HWND g_hWndStatus; static HWND g_hWndView; static HWND g_hEdtLine; static HWND g_hBtnDec; static HWND g_hBtnInc; static HWND g_hBtnPrint; static HGLOBAL g_hDevMode = NULL; static HGLOBAL g_hDevNames = NULL; static int g_iDpiX; static int g_iDpiY; static int g_iOffX; static int g_iOffY; static int g_aiZipSpan[] = {443, 70, 70, 76, 68, 68, 68}; static RECT g_arcZip[7]; static char g_acLine[BUFFER_SIZE]; static char *g_apcField[6]; static char *g_pcFile = NULL; // プロトタイプ宣言 LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void OnBtnPrint(HWND hWnd); void OnDropFiles(HWND hWnd, WPARAM wParam); void OnSize(WPARAM wParam, LPARAM lParam); void OnGetMinMaxInfo(LPARAM lParam); void OnCreate(HWND hWnd); void OnDestroy(); LRESULT CALLBACK WndProcView(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void OnPaint(HWND hWnd); void UpdateLine(int iDiff); void GetLine(int iLine); void AddressPrint(HDC hdc); HFONT EasyCreateFont(double dPointSize, int iAngle, const char *pcFace); void DrawName(HDC hdc, const char *pcName, int iX); void DrawChar(HDC hdc, const char *pcString, int iCount, RECT *pRect); void SetTitle(HWND hWnd); int LmmToDotX(int iLmm); int LmmToDotY(int iLmm); void TrimLf(char *pcStr); void Trace(const char *pcFormat, ...); int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { char acAppName[] = APPNAME; WNDCLASSEX wcex; HWND hWnd; MSG msg; g_hInstance = hInstance; // Main wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = g_hInstance; wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); wcex.lpszMenuName = NULL; wcex.lpszClassName = acAppName; wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION); RegisterClassEx(&wcex); // View wcex.lpfnWndProc = WndProcView; wcex.hIcon = NULL; wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszClassName = VIEWNAME; wcex.hIconSm = NULL; RegisterClassEx(&wcex); hWnd = CreateWindowEx( WS_EX_ACCEPTFILES, acAppName, // ClassName NULL, // WindowName WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, // x CW_USEDEFAULT, // y CW_USEDEFAULT, // Width CW_USEDEFAULT, // Height NULL, // WndParent NULL, // Menu g_hInstance, NULL); // Param if (hWnd == NULL) { return 0; } ShowWindow(hWnd, nCmdShow); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int)msg.wParam; } LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_BTN_DEC: UpdateLine(-1); break; case IDC_BTN_INC: UpdateLine(1); break; case IDC_BTN_PRINT: OnBtnPrint(hWnd); break; } break; case WM_DROPFILES: OnDropFiles(hWnd, wParam); DragFinish((HDROP)wParam); break; case WM_SIZE: OnSize(wParam, lParam); break; case WM_GETMINMAXINFO: OnGetMinMaxInfo(lParam); break; case WM_CREATE: OnCreate(hWnd); break; case WM_DESTROY: OnDestroy(); PostQuitMessage(0); break; default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } return 0; } void OnBtnPrint(HWND hWnd) { PRINTDLG pd; HDC hdc; DOCINFO di; int iRet; Trace("OnBtnPrint\n"); memset(&pd, 0, sizeof(PRINTDLG)); pd.lStructSize = sizeof(PRINTDLG); pd.hwndOwner = hWnd; pd.hDevMode = g_hDevMode; pd.hDevNames = g_hDevNames; pd.Flags = PD_RETURNDC; if (PrintDlg(&pd) == 0) { return; } if (g_hDevMode) { GlobalFree(g_hDevMode); } g_hDevMode = pd.hDevMode; if (g_hDevNames) { GlobalFree(g_hDevNames); } g_hDevNames = pd.hDevNames; hdc = pd.hDC; if (hdc == NULL) { return; } g_iDpiX = GetDeviceCaps(hdc, LOGPIXELSX); g_iDpiY = GetDeviceCaps(hdc, LOGPIXELSY); g_iOffX = GetDeviceCaps(hdc, PHYSICALOFFSETX); g_iOffY = GetDeviceCaps(hdc, PHYSICALOFFSETY); Trace("Dpi=%d,%d\n", g_iDpiX, g_iDpiY); Trace("Off=%d,%d\n", g_iOffX, g_iOffY); di.cbSize = sizeof(DOCINFO); di.lpszDocName = APPNAME; di.lpszOutput = NULL; di.lpszDatatype = NULL; di.fwType = 0; iRet = StartDoc(hdc, &di); iRet = StartPage(hdc); AddressPrint(hdc); iRet = EndPage(hdc); iRet = EndDoc(hdc); DeleteDC(hdc); } void OnDropFiles(HWND hWnd, WPARAM wParam) { HDROP hDrop; char acPath[_MAX_PATH]; char acExt[_MAX_EXT]; hDrop = (HDROP)wParam; DragQueryFile(hDrop, 0, acPath, sizeof(acPath)); _splitpath(acPath, NULL, NULL, NULL, acExt); if (_stricmp(acExt, ".csv")) { return; } if (g_pcFile) { free(g_pcFile); } g_pcFile = _strdup(acPath); SetTitle(hWnd); SetWindowText(g_hEdtLine, NULL); UpdateLine(1); } void OnSize(WPARAM wParam, LPARAM lParam) { RECT rc; int iMainWidth; int iMainHeight; int iViewWidth; int iViewHeight; int iX; int iY; int iWidth; SendMessage(g_hWndStatus, WM_SIZE, wParam, lParam); if (wParam == SIZE_MINIMIZED) { return; } iMainWidth = LOWORD(lParam); iMainHeight = HIWORD(lParam); Trace("OnSize (%d,%d)\n", iMainWidth, iMainHeight); GetWindowRect(g_hWndStatus, &rc); iMainHeight -= rc.bottom - rc.top; // とりあえず高さを基準にする iViewHeight = iMainHeight - 8 - 36; iViewWidth = iViewHeight * 100 / 148; MoveWindow(g_hWndView, (iMainWidth - iViewWidth) / 2, 8, iViewWidth, iViewHeight, TRUE); iY = iMainHeight - 36 + 8; iX = 8; MoveWindow(g_hEdtLine, iX, iY, iWidth = 32, 24, TRUE); iX += iWidth + 8; MoveWindow(g_hBtnDec, iX, iY, iWidth = 32, 24, TRUE); iX += iWidth + 8; MoveWindow(g_hBtnInc, iX, iY, iWidth = 32, 24, TRUE); iX += iWidth + 8; MoveWindow(g_hBtnPrint, iX, iY, iWidth = 80, 24, TRUE); } void OnGetMinMaxInfo(LPARAM lParam) { MINMAXINFO *pmmi; pmmi = (MINMAXINFO*)lParam; pmmi->ptMinTrackSize.x = 240; pmmi->ptMinTrackSize.y = 120; } void OnCreate(HWND hWnd) { int iLeft; int i; SetTitle(hWnd); g_hWndStatus = CreateStatusWindow(WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP, NULL, hWnd, IDC_WND_STATUS); g_hWndView = CreateWindow(VIEWNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hWnd, (HMENU)IDC_WND_VIEW, g_hInstance, NULL); g_hEdtLine = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hWnd, (HMENU)IDC_EDT_LINE, g_hInstance, NULL); g_hBtnDec = CreateWindow("BUTTON", "<", WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hWnd, (HMENU)IDC_BTN_DEC, g_hInstance, NULL); g_hBtnInc = CreateWindow("BUTTON", ">", WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hWnd, (HMENU)IDC_BTN_INC, g_hInstance, NULL); g_hBtnPrint = CreateWindow("BUTTON", "Print", WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hWnd, (HMENU)IDC_BTN_PRINT, g_hInstance, NULL); iLeft = 0; for (i = 0; i < 7; i++) { iLeft += g_aiZipSpan[i]; g_arcZip[i].left = iLeft; g_arcZip[i].top = 120; g_arcZip[i].right = g_arcZip[i].left + 57; g_arcZip[i].bottom = g_arcZip[i].top + 80; } GetLine(0); } void OnDestroy() { if (g_hDevMode) { GlobalFree(g_hDevMode); } if (g_hDevNames) { GlobalFree(g_hDevNames); } if (g_pcFile != NULL) { free(g_pcFile); } } LRESULT CALLBACK WndProcView(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_PAINT: OnPaint(hWnd); break; default: return DefWindowProc(hWnd, uMsg, wParam, lParam); } return 0; } void OnPaint(HWND hWnd) { PAINTSTRUCT ps; HDC hdc; RECT rect; RECT rc; HPEN hpen; HPEN hpenOld; int i; hdc = BeginPaint(hWnd, &ps); GetClientRect(hWnd, &rect); g_iDpiX = (int)(25.4 * rect.right / 100.0); g_iDpiY = (int)(25.4 * rect.bottom / 148.0); g_iOffX = 0; g_iOffY = 0; SetBkMode(hdc, TRANSPARENT); hpen = CreatePen(PS_SOLID, 1, RGB(255, 0, 0)); hpenOld = SelectObject(hdc, hpen); for (i = 0; i < _countof(g_arcZip); i++) { rc.left = LmmToDotX(g_arcZip[i].left); rc.top = LmmToDotY(g_arcZip[i].top); rc.right = LmmToDotX(g_arcZip[i].right); rc.bottom = LmmToDotY(g_arcZip[i].bottom); Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom); } Rectangle(hdc, 0, LmmToDotY(1250), rect.right, rect.bottom); SelectObject(hdc, hpenOld); DeleteObject(hpen); AddressPrint(hdc); EndPaint(hWnd, &ps); } void UpdateLine(int iDiff) { char acBuf[4]; int iLine; int iRet; iLine = 0; iRet = GetWindowText(g_hEdtLine, acBuf, sizeof(acBuf)); if (0 < iRet) { sscanf(acBuf, "%d", &iLine); } iLine += iDiff; if (iLine < 1) iLine = 1; if (999 < iLine) iLine = 999; GetLine(iLine); sprintf(acBuf, "%d", iLine); SetWindowText(g_hEdtLine, acBuf); InvalidateRect(g_hWndView, NULL, TRUE); UpdateWindow(g_hWndView); } void GetLine(int iLine) { FILE *pfile; u_char *puc; char *pcField; int iField; int i; // フィールド初期化 memset(g_apcField, 0, sizeof(g_apcField)); if (g_pcFile == NULL) { return; } pfile = fopen(g_pcFile, "rt"); if (pfile == NULL) { return; } // 読み飛ばし for (i = 0; i < iLine; i++) { if (fgets(g_acLine, sizeof(g_acLine), pfile) == NULL) { g_acLine[0] = '\0'; break; } } fclose(pfile); // 改行文字削除 TrimLf(g_acLine); // 行をフィールドに分解する iField = 0; g_apcField[iField++] = g_acLine; for (puc = g_acLine; *puc; puc++) { if (*puc == ',') { *puc = '\0'; if (_countof(g_apcField) <= iField) { break; } g_apcField[iField++] = puc + 1; } } // 郵便番号フィールドから数字以外を取り除く pcField = g_apcField[0]; for (puc = pcField; *puc; puc++) { if (isdigit(*puc)) { *(pcField++) = *puc; } } *pcField = *puc; } void AddressPrint(HDC hdc) { HFONT hFont; HFONT hFontOld; char *pcField; int i; // 郵便番号 pcField = g_apcField[0]; if (pcField) { hFont = EasyCreateFont(14.0, 0, "MS 明朝"); hFontOld = SelectObject(hdc, hFont); for (i = 0; i < 7 && pcField[i]; i++) { DrawChar(hdc, &pcField[i], 1, &g_arcZip[i]); } SelectObject(hdc, hFontOld); DeleteObject(hFont); } // 住所 hFont = EasyCreateFont(16.0, 2700, "@MS 明朝"); hFontOld = SelectObject(hdc, hFont); pcField = g_apcField[1]; if (pcField) { TextOut(hdc, LmmToDotX(900), LmmToDotY(250), pcField, (int)strlen(pcField)); } pcField = g_apcField[2]; if (pcField) { TextOut(hdc, LmmToDotX(820), LmmToDotY(350), pcField, (int)strlen(pcField)); } pcField = g_apcField[3]; if (pcField) { TextOut(hdc, LmmToDotX(740), LmmToDotY(350), pcField, (int)strlen(pcField)); } SelectObject(hdc, hFontOld); DeleteObject(hFont); // 名前 hFont = EasyCreateFont(24.0, 2700, "@MS 明朝"); hFontOld = SelectObject(hdc, hFont); DrawName(hdc, g_apcField[4], 550); DrawName(hdc, g_apcField[5], 450); SelectObject(hdc, hFontOld); DeleteObject(hFont); } HFONT EasyCreateFont(double dPointSize, int iAngle, const char *pcFace) { int iHeight; HFONT hFont; iHeight = (int)(dPointSize * g_iDpiY / 72); hFont = CreateFont( iHeight, 0, iAngle, iAngle, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, pcFace); return hFont; } void DrawName(HDC hdc, const char *pcName, int iX) { int iLen; int iY; int i; if (! pcName) { return; } iLen = (int)strlen(pcName); if (iLen < 2) { return; } iLen /= 2; for (i = 0; i < iLen; i++) { iY = 300 + 800 * i / iLen; TextOut(hdc, LmmToDotX(iX), LmmToDotY(iY), pcName + i * 2, 2); } iY = 300 + 800; TextOut(hdc, LmmToDotX(iX), LmmToDotY(iY), "様", 2); } void DrawChar(HDC hdc, const char *pcString, int iCount, RECT *pRect) { RECT rc; rc.left = LmmToDotX(pRect->left); rc.top = LmmToDotY(pRect->top); rc.right = LmmToDotX(pRect->right); rc.bottom = LmmToDotY(pRect->bottom); DrawText(hdc, pcString, iCount, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER); } void SetTitle(HWND hWnd) { char acFname[_MAX_FNAME]; char acExt[_MAX_EXT]; char acTitle[512]; if (g_pcFile != NULL) { _splitpath(g_pcFile, NULL, NULL, acFname, acExt); strcat(acFname, acExt); } else { strcpy(acFname, "無題"); } sprintf(acTitle, "%s - %s", acFname, APPNAME); SetWindowText(hWnd, acTitle); } int LmmToDotX(int iLmm) { return iLmm * g_iDpiX / 254 - g_iOffX; } int LmmToDotY(int iLmm) { return iLmm * g_iDpiY / 254 - g_iOffY; } void TrimLf(char *pcStr) { int iLen; iLen = (int)strlen(pcStr); if (0 < iLen && pcStr[iLen - 1] == '\n') { pcStr[iLen - 1] = '\0'; } } void Trace(const char *pcFormat, ...) { va_list args; char acBuf[512]; int iRet; va_start(args, pcFormat); iRet = _vsnprintf(acBuf, sizeof(acBuf), pcFormat, args); if (0 < iRet) { OutputDebugString(acBuf); } va_end(args); }