Skip to content

Instantly share code, notes, and snippets.

@kou1okada
Created November 1, 2016 06:21
Show Gist options
  • Save kou1okada/e8016c543ee0677dba236978bae9bbe7 to your computer and use it in GitHub Desktop.
Save kou1okada/e8016c543ee0677dba236978bae9bbe7 to your computer and use it in GitHub Desktop.
Win32 API - ReaderMode Example
cmake_minimum_required(VERSION 2.8)
set(CMAKE_LEGACY_CYGWIN_WIN32 0)
project(ReaderModeExample)
if(MSVC)
add_compile_options("/MP")
endif()
add_executable(ReaderModeExample WIN32
ReaderModeExample.c
ReaderMode.c
ReaderMode.h
)
# Makefile for make and nmake
all: ReaderModeExample
ReaderModeExample: ReaderModeExample.c ReaderMode.c ReaderMode.h
$(CC) -o ReaderModeExample ReaderModeExample.c ReaderMode.c
clean:
-$(RM) DEL /Q /S ReadModeExample ReaderModeExample.exe ReaderModeExample.obj ReaderMode.obj
/** @file
* ReaderMode API
* Copyright (c) 2016 Koichi OKADA. All right reserved.
* This code is distributed under the MIT license.
*/
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include "ReaderMode.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void (WINAPI *DLLDOREADERMODEPROC)(_In_ PREADERMODEINFO prmi);
static DLLDOREADERMODEPROC pDoReaderMode = NULL;
static LPCTSTR lpszDllName = _T("C:\\Windows\\System32\\comctl32.dll");
static HINSTANCE hinstDll = NULL;
/**
* Free ReaderMode API.
* @remarks This function is called automatically.
*/
static void FreeReaderMode(void) {
if (hinstDll) {
FreeLibrary(hinstDll);
}
}
/**
* Load ReaderMode API.
* @remarks This function is called automatically.
*/
static DLLDOREADERMODEPROC LoadReaderMode()
{
pDoReaderMode = NULL;
atexit(FreeReaderMode);
hinstDll = LoadLibrary(lpszDllName);
if (!hinstDll) {
fprintf(stderr, "Error: in %s line %d: LoadLibrary failed: %s\n", __FILE__, __LINE__, lpszDllName);
exit(EXIT_FAILURE);
}
pDoReaderMode = (DLLDOREADERMODEPROC)GetProcAddress(hinstDll, MAKEINTRESOURCE(383)); // DoReaderMode @ 383
if (!pDoReaderMode) {
fprintf(stderr, "Error: in %s line %d: GetProcAddress failed: DoReaderMode\n", __FILE__, __LINE__);
exit(EXIT_FAILURE);
}
return pDoReaderMode;
}
void WINAPI DoReaderMode(_In_ PREADERMODEINFO prmi)
{
if (!pDoReaderMode) {
LoadReaderMode();
}
if (pDoReaderMode) {
pDoReaderMode(prmi);
}
}
#ifdef __cplusplus
}
#endif
/** @file
* ReaderMode API
* Copyright (c) 2016 Koichi OKADA. All right reserved.
* This code is distributed under the MIT license.
*/
#ifndef READERMODE_H
#define READERMODE_H
#include <windows.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @see [READERMODEINFO structure](https://msdn.microsoft.com/en-us/library/windows/desktop/bb775524.aspx)
*/
typedef struct tagReaderModeInfo READERMODEINFO, *PREADERMODEINFO;
/**
* @see [ReaderScroll callback function](https://msdn.microsoft.com/en-us/library/windows/desktop/bb775729.aspx)
*/
typedef BOOL (CALLBACK *PFNREADERSCROLL)(_In_ PREADERMODEINFO prmi, _In_ int dx, _In_ int dy);
/**
* @see [TranslateDispatch callback function](https://msdn.microsoft.com/en-us/library/windows/desktop/bb775736.aspx)
*/
typedef BOOL (CALLBACK *PFNREADERTRANSLATEDISPATCH)(_In_ LPMSG lpmsg);
/**
* @see [READERMODEINFO structure](https://msdn.microsoft.com/en-us/library/windows/desktop/bb775524.aspx)
*/
struct tagReaderModeInfo {
UINT cbSize;
HWND hwnd;
DWORD fFlags;
LPRECT prc;
PFNREADERSCROLL pfnScroll;
PFNREADERTRANSLATEDISPATCH pfnDspatch;
LPARAM lParam;
};
#define RMF_ZEROCURSOR 0x01
#define RMF_VERTICALONLY 0x02
#define RMF_HORIZONTALONLY 0x04
/**
* @see [DoReaderMode function](https://msdn.microsoft.com/en-us/library/windows/desktop/bb775524.aspx)
*/
void WINAPI DoReaderMode(_In_ PREADERMODEINFO prmi);
#ifdef __cplusplus
}
#endif
#endif//READERMODE_H
/** @file
* ReaderMode API Example
* Copyright (c) 2016 Koichi OKADA. All right reserved.
* This code is distributed under the MIT license.
*/
#include <windows.h>
#include <windowsx.h>
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#include <commctrl.h>
#include "ReaderMode.h"
#pragma comment(lib, "user32.lib")
BOOL CALLBACK ReaderScrollCallback(PREADERMODEINFO prmi, int dx, int dy)
{
static int i = 0;
fprintf(stderr, "%6d: %3d, %3d\n", i++, dx, dy);
return TRUE; // always true
}
static BOOL rmfirst; // ReaderMode first pass flag.
static BOOL rmmoved; // ReaderMode moved flag.
static int rmx0, rmy0; // ReaderMode initial position.
BOOL CALLBACK TranslateDispatchCallback(LPMSG lpmsg)
{
static int x0, y0;
BOOL fResult = FALSE; // TRUE handled msg, FALSE did not handle msg and msg will be handleded fault handler.
fprintf(stderr, "msg: %04x\n", lpmsg->message);
switch (lpmsg->message) {
case WM_MOUSEMOVE:
if (rmfirst) {
rmfirst = FALSE;
rmmoved = FALSE;
rmx0 = lpmsg->pt.x;
rmy0 = lpmsg->pt.y;
} else if (rmx0 != lpmsg->pt.x || rmy0 != lpmsg->pt.y) {
rmmoved = TRUE;
}
fprintf(stderr, " : %3d, %3d\n", lpmsg->pt.x, lpmsg->pt.y);
break;
case WM_MBUTTONUP:
if (rmfirst || !rmmoved) {
fResult = TRUE; // Keep ReaderMode if cursor did not move.
} else {
// WM_MBUTTONUP will finish ReaderMode at default handler.
// But cursor will not be recoverd.
SetCursor(LoadCursor(NULL, IDC_ARROW)); // Set deafult cursor.
}
break;
}
return fResult;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) {
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_MBUTTONDOWN:
{
int x = GET_X_LPARAM(lParam);
int y = GET_Y_LPARAM(lParam);
int w = 8;
RECT r = {x-w, y-w, x+w, y+w};
READERMODEINFO rmi = {
sizeof(READERMODEINFO),
hwnd,
RMF_ZEROCURSOR,
&r,
ReaderScrollCallback,
TranslateDispatchCallback,
0
};
rmfirst = TRUE;
DoReaderMode(&rmi);
}
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
const TCHAR CLASS_NAME[] = _T("ReaderModeExample");
WNDCLASS wc = {
0, // Style
WndProc, // WndProc
0, // ClsWxtra
0, // WndExtra
hInstance, // Instance
NULL, // Icon
LoadCursor(NULL, IDC_ARROW), // Cursor
NULL, // BG
NULL, // Menu name
CLASS_NAME // Class name
};
RegisterClass(&wc);
HWND hwnd = CreateWindowEx(
0, // Optional window style
CLASS_NAME, // Window class
CLASS_NAME, // Window text
WS_OVERLAPPEDWINDOW, // Window style
CW_USEDEFAULT, // x
CW_USEDEFAULT, // y
CW_USEDEFAULT, // w
CW_USEDEFAULT, // h
NULL, // Parent window
NULL, // Menu
hInstance, // Instance
NULL // Additional application data
);
if (hwnd == NULL) {
fprintf(stderr, "Error: in %s line %d: CreateWindowEx failed.\n", __FILE__, __LINE__);
return EXIT_FAILURE;
}
ShowWindow(hwnd, nCmdShow);
MSG msg;
while (GetMessage(&msg, NULL, 0,0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment