📄 wnduserrng.c
字号:
// Description:
// By Sarah Dean
// Email: sdean12@sdean12.org
// WWW: http://www.FreeOTFE.org/
//
// -----------------------------------------------------------------------------
//
#include <windows.h>
#include <Windowsx.h> // Needed for GET_X_LPARAM, GET_Y_LPARAM macros
#include <commctrl.h>
#include <stdlib.h> // Needed for itow(...)
#include "FreeOTFEDebug.h"
#include "FreeOTFEGUIlib.h"
#include "wndUserRNG.h"
#include "main.h"
#include "FreeOTFElib.h"
#define POINTS_TO_A_LINE 2
struct POINTLIST {
POINT Point;
struct POINTLIST* Prev;
struct POINTLIST* Next;
};
typedef struct POINTLIST *PPOINTLIST;
typedef struct _USERRNG_DATA {
CREATESTRUCT CreateStruct;
// This stores the random data as it is generated
FREEOTFEBYTE RandomByte;
// This stores the number of random bits in RandomByte
int RandomByteBits;
int PointCount;
PPOINTLIST LinesListHead;
PPOINTLIST LinesListTail;
POINT LastPnt;
int TrailLines;
int LineWidth;
COLORREF LineColor;
DWORD TimeOfLastSample;
// Callbacks...
USERRNG_BITGENPROC ProcBitGen;
USERRNG_BYTEGENPROC ProcByteGen;
USERRNG_SAMPLEPROC ProcSample;
} USERRNG_DATA, *PUSERRNG_DATA;
// =========================================================================
// Forward declarations...
void wndUserRNG_SetWindowData(HWND hWnd, USERRNG_DATA* WindowData);
USERRNG_DATA* wndUserRNG_GetWindowData(HWND hWnd);
void _wndUserRNG_DrawLine(
HWND hWnd,
int Mode,
POINT A,
POINT B
);
// =========================================================================
LRESULT CALLBACK wndUserRNG_HandleMsg_WM_CREATE(HWND hWnd, LPARAM lParam)
{
LRESULT retval = -1; // Assume failure
USERRNG_DATA* WindowData;
DEBUGOUTGUI(DEBUGLEV_ENTER, (TEXT("wndUserRNG_HandleMsg_WM_CREATE\n")));
WindowData = malloc(sizeof(*WindowData));
if (WindowData != NULL)
{
memset(WindowData, 0, sizeof(WindowData));
WindowData->RandomByte = 0;
WindowData->RandomByteBits = 0;
WindowData->PointCount = 0;
WindowData->LinesListHead = NULL;
WindowData->LinesListTail = NULL;
WindowData->LastPnt.x = -1;
WindowData->LastPnt.y = -1;
WindowData->TrailLines = USERRNG_DEFAULT_TRAILLINES;
WindowData->LineWidth = USERRNG_DEFAULT_LINEWIDTH;
WindowData->LineColor = USERRNG_DEFAULT_LINECOLOR;
WindowData->ProcBitGen = NULL;
WindowData->ProcByteGen = NULL;
WindowData->ProcSample = NULL;
WindowData->CreateStruct = *((CREATESTRUCT*)lParam);
wndUserRNG_SetWindowData(hWnd, WindowData);
WindowData->TimeOfLastSample = 0;
// Success
retval = 0;
}
DEBUGOUTGUI(DEBUGLEV_EXIT, (TEXT("wndUserRNG_HandleMsg_WM_CREATE\n")));
return retval;
}
// =========================================================================
// Remove the last point from the tail of the linked list of points
void RemoveLastPoint(USERRNG_DATA* WindowData)
{
PPOINTLIST tmpPoint;
if (WindowData->LinesListTail != NULL)
{
tmpPoint = WindowData->LinesListTail;
WindowData->LinesListTail = WindowData->LinesListTail->Next;
if (WindowData->LinesListTail != NULL)
{
WindowData->LinesListTail->Prev = NULL;
}
// Overwrite position before discarding record
SecZeroAndFreeMemory(tmpPoint, sizeof(*tmpPoint));
WindowData->PointCount--;
}
if (WindowData->LinesListTail == NULL)
{
WindowData->LinesListHead = NULL;
}
}
// =========================================================================
// Add a new last point onto the head of the linked list of points
void StoreNewPoint(
USERRNG_DATA* WindowData,
POINT pnt
)
{
PPOINTLIST tmpPoint;
tmpPoint = malloc(sizeof(*tmpPoint));
if (tmpPoint != NULL)
{
tmpPoint->Point = pnt;
tmpPoint->Next = NULL;
tmpPoint->Prev = WindowData->LinesListHead;
if (WindowData->LinesListHead != NULL)
{
WindowData->LinesListHead->Next = tmpPoint;
}
WindowData->LinesListHead = tmpPoint;
WindowData->PointCount++;
if (WindowData->LinesListTail == NULL)
{
WindowData->LinesListTail = WindowData->LinesListHead;
}
}
}
// =========================================================================
void wndUserRNG_CallbackBit(
HWND hWnd,
USERRNG_BIT Bit
)
{
USERRNG_DATA* WindowData;
NMUSERRNG_BITGEN nm;
WindowData = wndUserRNG_GetWindowData(hWnd);
// Callback proc
if (WindowData->ProcBitGen != NULL)
{
WindowData->ProcBitGen(hWnd, Bit);
}
// If possible, notify parent hWnd
if (WindowData->CreateStruct.hMenu != 0)
{
nm.hdr.hwndFrom = hWnd;
nm.hdr.idFrom = (UINT)WindowData->CreateStruct.hMenu;
nm.hdr.code = URNG_BITGEN;
nm.Bit = Bit;
SendMessage(
WindowData->CreateStruct.hwndParent,
WM_NOTIFY,
(UINT)WindowData->CreateStruct.hMenu,
(LPARAM)(&nm)
);
}
}
// =========================================================================
void wndUserRNG_CallbackByte(
HWND hWnd,
USERRNG_BYTE Byte
)
{
USERRNG_DATA* WindowData;
NMUSERRNG_BYTEGEN nm;
WindowData = wndUserRNG_GetWindowData(hWnd);
// Callback proc
if (WindowData->ProcByteGen != NULL)
{
WindowData->ProcByteGen(hWnd, Byte);
}
// If possible, notify parent hWnd
if (WindowData->CreateStruct.hMenu != 0)
{
nm.hdr.hwndFrom = hWnd;
nm.hdr.idFrom = (UINT)WindowData->CreateStruct.hMenu;
nm.hdr.code = URNG_BYTEGEN;
nm.Byte = Byte;
SendMessage(
WindowData->CreateStruct.hwndParent,
WM_NOTIFY,
(UINT)WindowData->CreateStruct.hMenu,
(LPARAM)(&nm)
);
}
}
// =========================================================================
void wndUserRNG_CallbackSample(
HWND hWnd,
POINT Pnt
)
{
USERRNG_DATA* WindowData;
NMUSERRNG_SAMPLE nm;
WindowData = wndUserRNG_GetWindowData(hWnd);
// Callback proc
if (WindowData->ProcSample != NULL)
{
WindowData->ProcSample(hWnd, Pnt);
}
// If possible, notify parent hWnd
if (WindowData->CreateStruct.hMenu != 0)
{
nm.hdr.hwndFrom = hWnd;
nm.hdr.idFrom = (UINT)WindowData->CreateStruct.hMenu;
nm.hdr.code = URNG_SAMPLE;
nm.Pnt = Pnt;
SendMessage(
WindowData->CreateStruct.hwndParent,
WM_NOTIFY,
(UINT)WindowData->CreateStruct.hMenu,
(LPARAM)(&nm)
);
}
}
// =========================================================================
void ProcessSample(
HWND hWnd,
POINT pnt
)
{
USERRNG_DATA* WindowData;
int i;
WindowData = wndUserRNG_GetWindowData(hWnd);
wndUserRNG_CallbackSample(hWnd, pnt);
// This stores the random data as it is generated
for (i = 1; i<= USERRNG_BITS_PER_SAMPLE; i++)
{
WindowData->RandomByte = (WindowData->RandomByte << 1);
WindowData->RandomByte = (WindowData->RandomByte + ((FREEOTFEBYTE)(pnt.x & 1)));
WindowData->RandomByteBits++;
wndUserRNG_CallbackBit(hWnd, ((USERRNG_BIT)(pnt.x & 1)));
WindowData->RandomByte = (WindowData->RandomByte << 1);
WindowData->RandomByte = (WindowData->RandomByte + (FREEOTFEBYTE)(pnt.y & 1));
WindowData->RandomByteBits++;
wndUserRNG_CallbackBit(hWnd, ((USERRNG_BIT)(pnt.y & 1)));
pnt.x = pnt.x >> 1;
pnt.y = pnt.y >> 1;
}
if (WindowData->RandomByteBits >= 8)
{
wndUserRNG_CallbackByte(hWnd, WindowData->RandomByte);
WindowData->RandomByteBits = 0;
WindowData->RandomByte = 0;
}
}
// =========================================================================
void _wndUserRNG_TakeSampleIfMoved(HWND hWnd)
{
BOOL changed = FALSE;
USERRNG_DATA* WindowData;
if (IsWindowEnabled(hWnd))
{
WindowData = wndUserRNG_GetWindowData(hWnd);
// Handle the situation in which no mouse co-ordinates have yet been taken
if (
(WindowData->LastPnt.x > -1) &&
(WindowData->LastPnt.y > -1)
)
{
// If there are no points, we have a new one
if (WindowData->PointCount == 0)
{
changed = TRUE;
}
else
{
// If the mouse cursor has moved a significant difference, use the new
// co-ordinates
// Both the X *and* Y mouse co-ordinates must have changed, to prevent
// the user from generating non-random data by simply moving the mouse in
// just a horizontal (or vertical) motion, in which case the X (or Y)
// position would change, but the Y (or X) position would remain
// relativly the same. This would only generate 1/2 as much random data
// The effects of the following code are trivial to see; simply waggle
// the mouse back and forth horizontally; instead of seeing a new dark
// line appearing (indicating that the sample has been taken), the
// inverse coloured line appears, indicating the mouse pointer
if (
(
(WindowData->LastPnt.x > (WindowData->LinesListHead->Point.x+USERRNG_MIN_DIFF)) ||
(WindowData->LastPnt.x < (WindowData->LinesListHead->Point.x-USERRNG_MIN_DIFF))
) &&
(
(WindowData->LastPnt.y > (WindowData->LinesListHead->Point.y+USERRNG_MIN_DIFF)) ||
(WindowData->LastPnt.y < (WindowData->LinesListHead->Point.y-USERRNG_MIN_DIFF))
)
)
{
changed = TRUE;
}
}
}
if (!(changed))
{
// User hasn't moved cursor - delete oldest line until we catch up with
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -