c_cpp Windows实用程序功能
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c_cpp Windows实用程序功能相关的知识,希望对你有一定的参考价值。
// Copyright 2018 William Dang (william.dang@utah.edu)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#undef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdint.h>
#include <assert.h>
#include <vector>
#include <string>
#include <CommCtrl.h>
#include <CommDlg.h>
#include <Shlobj.h>
#include <Shellapi.h>
#include <windef.h>
// HANDLE_DIALOG_MSG is a version of HANDLE_MSG(windowsx.h) for dialog boxes
#define HANDLE_DIALOG_MSG(hWnd, message, fn) case (message): \
return (SetDlgMsgResult(hWnd, uMsg, HANDLE_ ## message((hWnd), (wParam), (lParam), (fn))))
// Returns a readable string representation of a window message
const char* MessageString(UINT message);
// Encodes the given utf-16 string to utf-8
std::string UTF8(const wchar_t* utf16, size_t count);
template<size_t N>
inline std::string UTF8(const wchar_t (&utf16)[N]) {
return UTF8(utf16, N);
}
inline std::string UTF8(const std::wstring& utf16) {
return UTF8(&utf16[0], utf16.size());
}
// Encodes the given utf-8 string to utf-16
std::wstring UTF16(const char* utf8, size_t count);
template<size_t N>
inline std::wstring UTF16(const char(&utf8)[N]) {
return UTF16(utf8, N);
}
inline std::wstring UTF16(const std::string& utf8) {
return UTF16(&utf8[0], utf8.size());
}
#ifdef __cplusplus
extern "C" {
#endif
inline int LogicalUnitsToPoints(HDC dc, int lu) {
return -MulDiv(lu, 72, GetDeviceCaps(dc, LOGPIXELSY));
}
inline int PointsToLogicalUnits(HDC dc, int pt) {
return -MulDiv(pt, GetDeviceCaps(dc, LOGPIXELSY), 72);
}
// Force the system to create a message queue for the calling thread.
// A thread needs a message queue in order to receive posted messages
// from PostThreadMessage.
inline void ForceMessageQueueForThread() {
MSG msg;
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
}
// Retrieve the HINSTANCE of the module we've been linked into.
// The Microsoft linker also provides a pseudo variable __ImageBase:
// extern "C" IMAGE_DOS_HEADER __ImageBase
// (HINSTANCE)&__ImageBase
//
// see:
// http://blogs.msdn.com/b/oldnewthing/archive/2004/10/25/247180.aspx
inline HINSTANCE GetCurrentModule() {
HINSTANCE hinstance;
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT
| GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
(LPCTSTR)GetCurrentModule,
&hinstance);
return hinstance;
}
// Center the window on the monitor containing the given window
// http://msdn.microsoft.com/en-us/library/dd162826(VS.85).aspx
inline void CenterWindow(HWND hwnd) {
RECT rect;
GetWindowRect(hwnd, &rect);
MONITORINFO mi = {sizeof(MONITORINFO)};
GetMonitorInfo(MonitorFromRect(&rect, MONITOR_DEFAULTTONEAREST), &mi);
SetWindowPos(hwnd, 0, (mi.rcWork.right/2)/2, (mi.rcWork.bottom/2)/2, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
}
inline CHOOSEFONTW FontFromFontDialog(HWND owner) {
CHOOSEFONTW cf = {sizeof(cf)};
LOGFONT logfont = {0};
cf.hwndOwner = owner;
cf.lpLogFont = &logfont;
cf.hInstance = GetCurrentModule();
cf.Flags = CF_EFFECTS;
ChooseFontW(&cf);
return cf;
}
// 65,536 on all Windows platforms as of 06/22/2011
inline DWORD GetAllocationGranularity() {
SYSTEM_INFO info;
GetSystemInfo(&info);
return info.dwAllocationGranularity;
}
inline int InitAllCommonControls() {
static const INITCOMMONCONTROLSEX icc = {
sizeof(icc),
ICC_LISTVIEW_CLASSES | // listview, header
ICC_TREEVIEW_CLASSES | // treeview, tooltips
ICC_BAR_CLASSES | // toolbar, statusbar, trackbar, tooltips
ICC_TAB_CLASSES | // tab, tooltips
ICC_UPDOWN_CLASS | // updown
ICC_PROGRESS_CLASS | // progress
ICC_HOTKEY_CLASS | // hotkey
ICC_ANIMATE_CLASS | // animate
ICC_WIN95_CLASSES | //
ICC_DATE_CLASSES | // month picker, date picker, time picker, updown
ICC_USEREX_CLASSES | // comboex
ICC_COOL_CLASSES | // rebar (coolbar) control
ICC_INTERNET_CLASSES | // IP address class.
ICC_NATIVEFNTCTL_CLASS | // native font control class.
ICC_STANDARD_CLASSES | // intrinsic User32 control classes: button, edit, static, listbox, combobox, and scroll bar
ICC_LINK_CLASS // hyperlink control class.
};
return InitCommonControlsEx(&icc);
}
// Returns the HWND that generated the given message.
inline HWND HWNDFromMessage(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) {
if(message == WM_PARENTNOTIFY) {
switch(LOWORD(wparam)) {
case WM_CREATE:
case WM_DESTROY: return reinterpret_cast<HWND>(lparam);
default: return GetDlgItem(hwnd, HIWORD(wparam));
}
}
switch(message) {
case WM_NOTIFY:
return reinterpret_cast<NMHDR*>(lparam)->hwndFrom;
case WM_COMMAND: return reinterpret_cast<HWND>(lparam);
case WM_CONTEXTMENU: return reinterpret_cast<HWND>(wparam);
case WM_CTLCOLORBTN:
case WM_CTLCOLORDLG:
case WM_CTLCOLOREDIT:
case WM_CTLCOLORLISTBOX:
case WM_CTLCOLORMSGBOX:
case WM_CTLCOLORSCROLLBAR:
case WM_CTLCOLORSTATIC: return reinterpret_cast<HWND>(lparam);
case WM_DRAWITEM:
case WM_COMPAREITEM:
case WM_DELETEITEM: return (reinterpret_cast<DELETEITEMSTRUCT*>(lparam))->hwndItem;
case WM_VKEYTOITEM:
case WM_CHARTOITEM:
case WM_HSCROLL:
case WM_VSCROLL: return reinterpret_cast<HWND>(lparam);
case WM_MEASUREITEM: return GetDlgItem(hwnd, reinterpret_cast<MEASUREITEMSTRUCT*>(lparam)->CtlID);
default: return hwnd;
}
}
ATOM RegisterWindowClass(const TCHAR* classname, WNDPROC);
inline void SetWindowIcon(HWND window, int id) {
SendMessage(window, WM_SETICON, ICON_BIG, (LPARAM)LoadIcon(
(HINSTANCE)GetWindowLongPtr(window, GWLP_HINSTANCE), MAKEINTRESOURCE(id)));
SendMessage(window, WM_SETICON, ICON_SMALL, (LPARAM) LoadIcon(
(HINSTANCE) GetWindowLongPtr(window, GWLP_HINSTANCE), MAKEINTRESOURCE(id)));
}
inline BOOL IsWin7orGreater() {
OSVERSIONINFOEX vesion_info = {sizeof(OSVERSIONINFOEX)};
vesion_info.dwMajorVersion = 6;
vesion_info.dwMinorVersion = 1;
DWORDLONG conditions = 0;
conditions = VerSetConditionMask(conditions, VER_MAJORVERSION, VER_GREATER_EQUAL);
conditions = VerSetConditionMask(conditions, VER_MINORVERSION, VER_GREATER_EQUAL);
return VerifyVersionInfo(&vesion_info, VER_MAJORVERSION | VER_MINORVERSION, conditions);
}
inline HGLRC InitializeOpenGL(HWND window) {
static PIXELFORMATDESCRIPTOR kDefaultGLPixelFormat = {
sizeof(PIXELFORMATDESCRIPTOR), // Size of this structure
1, // Version of this structure
PFD_DRAW_TO_WINDOW | // Draw to window (not to bitmap)
PFD_SUPPORT_OPENGL | // Support OpenGL calls in window
PFD_DOUBLEBUFFER, // The buffer is double-buffered,
PFD_TYPE_RGBA, // RGBA color mode
32, // Want 32-bit color
0, 0, 0, 0, 0, 0, // Not used to select mode RGB (Bits,Shifts)
0, 0, // Not used to select mode ALPHA (Bits,Shifts)
0, 0, 0, 0, 0, // Not used to select mode Accumbits, RGB(bits)
24, // Depth bits (z-axis)
8, // Specifies the depth of the stencil buffer.
0, // Auxiliary buffers are not supported.
0, // (Obsolete) and/or reserved
0, // No overlay and underlay planes
0, // (Obsolete) and/or reserved layer mask
0, // No transparent color for underlay plane
0 // (Obsolete)
};
HGLRC context = 0;
HDC dc = GetDC(window);
int format;
if(!(format = ChoosePixelFormat(dc, &kDefaultGLPixelFormat)))
return context;
if(!SetPixelFormat(dc, format, &kDefaultGLPixelFormat))
return context;
context = wglCreateContext(dc);
wglMakeCurrent(dc, context);
return context;
}
#ifdef __cplusplus
}
#endif
// Returns the selected filename from a file dialog or an empty string
inline std::string FilenameFromFileDialog(HWND owner = 0,
const char* filter = "All\0*.*\0\0") {
char buffer[MAX_PATH] = {0};
OPENFILENAMEA ofn = {sizeof(ofn)};
ofn.hwndOwner = owner;
ofn.hInstance = GetCurrentModule();
ofn.lpstrFilter = filter;
ofn.lpstrFile = buffer;
ofn.nFilterIndex = 1;
ofn.nMaxFile = MAX_PATH;
ofn.nMaxFileTitle = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_ENABLESIZING | OFN_FILEMUSTEXIST;
return GetOpenFileNameA(&ofn) == FALSE ?
std::string("") : std::string(ofn.lpstrFile);
}
inline std::wstring FilenameFromFileDialogW(HWND owner = 0,
const wchar_t* filter = L"All\0*.*\0\0") {
wchar_t buffer[MAX_PATH] = {0};
OPENFILENAMEW ofn = {sizeof(ofn)};
ofn.hwndOwner = owner;
ofn.hInstance = GetCurrentModule();
ofn.lpstrFilter = filter;
ofn.lpstrFile = buffer;
ofn.nFilterIndex = 1;
ofn.nMaxFile = MAX_PATH;
ofn.nMaxFileTitle = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_ENABLESIZING | OFN_FILEMUSTEXIST;
return GetOpenFileNameW(&ofn) == FALSE ? std::wstring(L"") : std::wstring(ofn.lpstrFile);
}
inline std::wstring FolderNameFromFolderDialog(HWND parent,
const std::wstring& title) {
BROWSEINFO bi = {0};
TCHAR buffer[MAX_PATH] = {0};
bi.hwndOwner = parent;
bi.pszDisplayName = buffer;
bi.lpszTitle = L""; //strTitle.get();
bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS | BIF_SHAREABLE;
OleInitialize(0);
const ITEMIDLIST* folder = SHBrowseForFolder(&bi);
if(folder && SHGetPathFromIDList(folder, buffer)) {
OleUninitialize();
return std::wstring(buffer);
}
OleUninitialize();
return std::wstring(L"");
}
inline std::wstring GetRoamingDirectoryW() {
wchar_t config_path[MAX_PATH] = {'\0'};
SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, config_path);
return std::wstring(config_path);
}
inline std::string GetRoamingDirectory() {
char config_path[MAX_PATH] = {'\0'};
SHGetFolderPathA(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, config_path);
return std::string(config_path);
}
// Size of the specified file without creating a handle.
// Returns -1 on failure.
inline int64_t GetFileSize(const std::wstring& path) {
int64_t size = -1;
WIN32_FILE_ATTRIBUTE_DATA attr;
if(GetFileAttributesEx(path.c_str(), GetFileExInfoStandard, &attr)) {
size = attr.nFileSizeHigh;
size = (size << 32) + attr.nFileSizeLow;
}
return size;
}
// Returns an __argv style vector where the first element
// is always THIS current process
inline std::vector<std::wstring> GetCommandLineWStrings() {
int argc;
wchar_t** wargv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
wchar_t wfile_path[MAX_PATH];
GetModuleFileNameW(GetCurrentModule(), wfile_path, MAX_PATH);
std::vector<std::wstring> result(wargv, wargv + argc);
result.insert(result.begin(), wfile_path);
LocalFree(wargv); // we're Responsible for GetModuleFileNameW's memory
return result;
}
// Returns an __argv style vector where the first element is always THIS
// current process
inline std::vector<std::string> GetCommandLineStrings() {
int argc;
wchar_t** wargv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
wchar_t wfile_path[MAX_PATH];
GetModuleFileNameW(GetCurrentModule(), wfile_path, MAX_PATH);
std::vector<std::wstring> result(wargv, wargv + argc);
std::vector<std::string> rv(result.size() + 1, "");
for(std::vector<std::wstring>::iterator i = result.begin(), end = result.end(); i!= end; ++i) {
std::string arg(i->begin(), i->end());
rv.push_back(arg);
}
std::string file_path(wfile_path, wfile_path + wcslen(wfile_path));
rv.insert(rv.begin(), file_path);
LocalFree(wargv); // we're Responsible for GetModuleFileNameW's memory
return rv;
}
// Load data from the given window handle
// returns a pointer to the stored data
template<class T>
inline T GetWindowData(HWND window) {
return reinterpret_cast<T>(GetWindowLongPtr(window, GWLP_USERDATA));
}
template<class T>
inline bool GetWindowData(HWND window,T** out) {
const LONG_PTR result = GetWindowLongPtr(window, GWLP_USERDATA);
if(result)
*out = reinterpret_cast<T>(result);
return !!result;
}
// store user data in the given window handle.
template<class T>
inline void SetWindowData(HWND window, T&& userdata) {
SetWindowLongPtr(window, GWLP_USERDATA, reinterpret_cast<uintptr_t>(userdata));
// Changes from SetWindowLongPtr will not take
// effect until SetWindowPos is called
// due to internal window data caching.
SetWindowPos(window, 0, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
}
// Load a pointer associated with the given window and identified
// by property_name into userdata
//
// returns *userdata
template<class T>
inline bool GetWindowProperty(const TCHAR* property_name, HWND window,
const T** out) {
HANDLE data = GetProp(window, property_name);
if(data) {
*out = reinterpret_cast<T*>(data);
return true;
}
return false;
}
template<class T>
inline T* GetWindowProperty(HWND window, const TCHAR* property_name) {
HANDLE data = GetProp(window, property_name);
if(data) {
T* userdata = reinterpret_cast<T*>(data);
return userdata;
}
return static_cast<T*>(0);
}
// Associates a pointer indentified by property_name with the given window
template<class T>
inline bool SetWindowProperty(HWND window, T* userdata, const TCHAR* property_name) {
return !!SetProp(window, property_name, static_cast<HANDLE>(userdata));
}
// calls GetLastError() and returns a readable string representation
// of the error
inline std::string GetLastErrorString() {
const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
const DWORD kBufferSize = 4096; // note: buffer cannot be larger than 64K bytes
const DWORD kCodeSize = 64; // size of HEX error code buffer
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
char buffer[kBufferSize] = { '\0' };
char code[kCodeSize] = { '\0' };
const int len_sans_null = FormatMessageA(kFlags, 0, hr, 0, buffer, kBufferSize, NULL);
sprintf_s(code, kCodeSize, " (0x%08X)", hr);
std::string result(buffer, buffer + len_sans_null - 2); // remove CRLF
result.append(code);
return result;
}
inline std::wstring GetLastErrorStringW() {
const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
const DWORD kBufferSize = 4096; // note: buffer cannot be larger than 64K bytes
const DWORD kCodeSize = 64; // size of HEX error code buffer
const HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
wchar_t buffer[kBufferSize] = { '\0' };
wchar_t code[kCodeSize] = { '\0' };
const int len_sans_null = FormatMessageW(kFlags, 0, hr, 0, buffer, kBufferSize, NULL);
wsprintf(code, L" (0x%08X)", hr);
// remove CRLF
std::wstring result(buffer, buffer + len_sans_null - 2 * sizeof(wchar_t));
result.append(code);
return result;
}
// Force the system to create a message queue for the calling thread.
// A thread needs a message queue in order to receive posted messages
// from PostThreadMessage.
inline void CreateMessageQueueForThread() {
MSG msg;
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
}
// returns a list of exported names from the given dll
inline std::vector<std::string> DllExports(const TCHAR* library) {
// Issues with using
// DONT_RESOLVE_DLL_REFERENCES
// http://blogs.msdn.com/b/oldnewthing/archive/2005/02/14/372266.aspx
// Summary:
// using DONT_RESOLVE_DLL_REFERENCES causes GetModuleHandle to successfully
// return a function pointer that will crash if invoked.
//
//
// using it here is safe since routines in the given module are not going to
// be invoked.
// PE file format: http://msdn.microsoft.com/en-us/magazine/cc301808.aspx
HMODULE lib = LoadLibraryEx(library, NULL, DONT_RESOLVE_DLL_REFERENCES);
char* plib = reinterpret_cast<char*>(lib);
IMAGE_DOS_HEADER* header = reinterpret_cast<IMAGE_DOS_HEADER*>(plib);
std::vector<std::string> v;
if(header->e_magic != IMAGE_DOS_SIGNATURE)
return v;
IMAGE_NT_HEADERS* headers = reinterpret_cast<IMAGE_NT_HEADERS*>(plib + header->e_lfanew);
assert(headers->Signature == IMAGE_NT_SIGNATURE);
assert(headers->OptionalHeader.NumberOfRvaAndSizes > 0);
ptrdiff_t offset = headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
IMAGE_EXPORT_DIRECTORY* exports = reinterpret_cast<IMAGE_EXPORT_DIRECTORY*>(plib + offset);
void* names = plib + exports->AddressOfNames;
v.reserve(exports->NumberOfNames);
for(size_t i = 0; i < exports->NumberOfNames; i++) {
std::string export_name(plib + static_cast<DWORD*>(names)[i]);
v.push_back(export_name);
}
FreeLibrary(lib);
return v;
}
template<class T>
inline HRESULT CoCreateInProc(REFCLSID clsid, T** out) {
return CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, __uuidof(T),
reinterpret_cast<void**>(out));
}
inline HFONT MakeFont(int point_size, const std::string& font_name) {
HDC hdc = GetDC(0);
int logical_size = -MulDiv(point_size, GetDeviceCaps(hdc, LOGPIXELSY), 72);
ReleaseDC(0, hdc);
return CreateFontA(logical_size, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, font_name.c_str());
}
// Reads the given file located at 'filename' calling back 'func'
// on each line read. These functions also support very large files.
// The function signature for 'func' should be "similar" to:
//
// void func(uint64_t line_number, const std::string& line_contents);
//
// line counts for line_number start at 1
template<class Function>
inline void Readlines(const std::wstring& filename, Function&& func) {
HANDLE file = CreateFileW(filename.c_str(),
GENERIC_READ,
FILE_SHARE_READ,
0, // security: returned handle wont be inherited
OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL); // supplies file attributes, ignored with OPEN_EXISITING
uint64_t file_size;
GetFileSizeEx(file, (PLARGE_INTEGER)&file_size); //checking for INVALID_FILE_SIZE left out for brevity
// Create the file-mapping object.
HANDLE file_map = CreateFileMappingW(file,
0, // security: returned handle wont be inherited
PAGE_READONLY, //page protection, mapped views depend on this
0, // high order max size (system determined)
0, // low order max size (system determined)
0); // string to identify the file_map(interprocess)
CloseHandle(file);
SYSTEM_INFO sys_info;
GetSystemInfo(&sys_info);
DWORD block_size = sys_info.dwAllocationGranularity;
__int64 offset = 0;
__int64 line_count =0;
__int64 bytes_remaining = file_size;
std::wstring buffer(4096, '\0');
uint64_t line = 0;
do {
if(bytes_remaining < block_size) {
block_size = static_cast<DWORD>(bytes_remaining);
}
// map a view into our address space
unsigned char* block = static_cast<unsigned char*>(MapViewOfFile(file_map, FILE_MAP_READ,
static_cast<DWORD>(offset >> 32), // Starting byte
static_cast<DWORD>(offset & 0xFFFFFFFF), // in file
block_size)); // # of bytes to map
for(DWORD i = 0; i< block_size; ++i) {
if(block[i]!='\n') {
buffer.push_back(block[i]);
} else {
++line;
func(line, buffer);
buffer.clear();
}
}
// unmap the view or else we'll have mulitiple views in our address space
UnmapViewOfFile(block);
offset += block_size;
bytes_remaining -= block_size;
} while(bytes_remaining > 0);
CloseHandle(file_map);
}
// Readlines for strings
template<class Function>
inline void Readlines(const std::string& filename, Function&& func) {
HANDLE file = CreateFileA(filename.c_str(),
GENERIC_READ,
FILE_SHARE_READ,
0, // security: returned handle wont be inherited
OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL); // supplies file attributes, ignored with OPEN_EXISITING
uint64_t file_size;
GetFileSizeEx(file, (PLARGE_INTEGER)&file_size); //checking for INVALID_FILE_SIZE left out for brevity
// Create the file-mapping object.
HANDLE file_map = CreateFileMappingA(file,
0, // security: returned handle wont be inherited
PAGE_READONLY, //page protection, mapped views depend on this
0, // high order max size (system determined)
0, // low order max size (system determined)
0); // string to identify the file_map(interprocess)
CloseHandle(file);
SYSTEM_INFO sys_info;
GetSystemInfo(&sys_info);
DWORD block_size = sys_info.dwAllocationGranularity;
__int64 offset = 0;
__int64 line_count =0;
__int64 bytes_remaining = file_size;
std::string buffer(file_size, '\0');
uint64_t line = 0;
do {
if(bytes_remaining < block_size) {
block_size = static_cast<DWORD>(bytes_remaining);
}
// map a view into our address space
unsigned char* block = static_cast<unsigned char*>(MapViewOfFile(file_map, FILE_MAP_READ,
static_cast<DWORD>(offset >> 32), // Starting byte
static_cast<DWORD>(offset & 0xFFFFFFFF), // in file
block_size)); // # of bytes to map
for(DWORD i = 0; i< block_size; ++i) {
if(block[i]!='\n') {
buffer.push_back(block[i]);
} else {
++line;
func(line, buffer);
buffer.clear();
}
}
// unmap the view or else we'll have mulitiple views in our address space
UnmapViewOfFile(block);
offset += block_size;
bytes_remaining -= block_size;
} while(bytes_remaining > 0);
CloseHandle(file_map);
}
// simulate mouse movement to the given coordinates
inline void MouseMove(int x, int y) {
INPUT input = {0};
input.type = INPUT_MOUSE;
input.mi.dwFlags = MOUSEEVENTF_MOVE|MOUSEEVENTF_ABSOLUTE;
// normalized absolute screen coordinates
input.mi.dx = x * (65535 / GetSystemMetrics(SM_CXSCREEN)-1);
input.mi.dy = y * (65535 / GetSystemMetrics(SM_CYSCREEN)-1);
SendInput(1, &input, sizeof(input));
}
// Simulate right mouse click at the given coordinates
inline void MouseRightClick(int x, int y) {
INPUT input = {0};
input.type = INPUT_MOUSE;
input.mi.dwFlags = MOUSEEVENTF_RIGHTDOWN;
SendInput(1, &input, sizeof(input));
input.mi.dwFlags = MOUSEEVENTF_RIGHTUP;
SendInput(1, &input, sizeof(input));
}
// Simulate left mouse click at the given coordinates
inline void MouseLeftClick(int x, int y) {
INPUT input = {0};
input.type = INPUT_MOUSE;
input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
SendInput(1, &input, sizeof(input));
input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(1, &input, sizeof(input));
}
// simulate single keyboard presses
inline static void KeyPress(char key) {
INPUT input[2] = {0};
input[0].type = INPUT_KEYBOARD;
input[0].ki.wScan = key;
input[0].ki.dwFlags = KEYEVENTF_UNICODE;
input[1].type = INPUT_KEYBOARD;
input[1].ki.wScan = key;
input[1].ki.dwFlags = KEYEVENTF_UNICODE|KEYEVENTF_KEYUP;
SendInput(2, &input[0], sizeof(input[0]));
}
// simulate a string of keyboard presses
inline static void KeyPress(const std::string& keys) {
if(keys.empty()) return;
const size_t len = keys.size();
std::vector<INPUT> keypresses;
keypresses.reserve(len*2);
INPUT input = {0};
input.type = INPUT_KEYBOARD;
for(size_t i = 0; i < len; ++i) {
input.ki.wScan = keys[i];
input.ki.dwFlags = KEYEVENTF_UNICODE;
keypresses.push_back(input);
input.ki.dwFlags = KEYEVENTF_UNICODE|KEYEVENTF_KEYUP;
keypresses.push_back(input);
}
SendInput(len*2, &keypresses[0], sizeof(input));
}
以上是关于c_cpp Windows实用程序功能的主要内容,如果未能解决你的问题,请参考以下文章
c_cpp BrickstorOS的快速单文件网络统计实用程序
c_cpp 模具实用程序 - 终止带有错误消息和退出代码的C程序