├── .gitignore
├── Chapter10_ResponsiveHacks
├── Chapter10_ResponsiveHacks.vcxproj
└── main-responsiveHacks.cpp
├── Chapter11_SearchAlgorithms
├── Chapter11_SearchAlgorithms.cpp
├── Chapter11_SearchAlgorithms.vcxproj
├── Chapter11_SearchAlgorithms.vcxproj.filters
├── DummyWindow.cpp
├── DummyWindow.h
└── WindowCode.h
├── Chapter11_StateMachines
├── Chapter11_StateMachines.cpp
├── Chapter11_StateMachines.vcxproj
├── Chapter11_StateMachines.vcxproj.filters
└── Game.h
├── Chapter1_BasicMemory
├── Chapter1_BasicMemory.vcxproj
├── Chapter1_BasicMemory.vcxproj.filters
├── Location-BasicMem.h
└── game-BasicMem.cpp
├── Chapter1_MemoryPointers
├── Chapter1_MemoryPointers.vcxproj
├── Chapter2_MemoryPointers.filters
├── Location-MemPointer.h
└── game-MemPointer.cpp
├── Chapter2_BasicDebugging
├── Chapter2_BasicDebugging.filters
├── Chapter2_BasicDebugging.vcxproj
├── Location-BasicDebugging.h
└── game-BasicDebugging.cpp
├── Chapter3_CloseMutex
├── Chapter3_CloseMutex.filters
├── Chapter3_CloseMutex.vcxproj
├── Location-CloseMutex.h
└── game-CloseMutex.cpp
├── Chapter3_FindingFiles
├── Chapter3_FindingFiles.filters
├── Chapter3_FindingFiles.vcxproj
├── Location-FindingFiles.h
└── game-FindingFiles.cpp
├── Chapter4_CodeToMemory
├── Chapter4_CodeToMemory.filters
├── Chapter4_CodeToMemory.vcxproj
└── main-codeToMemory.cpp
├── Chapter5_AdvancedMemoryForensics_Scanning
├── Chapter5_AdvancedMemoryForensics_Scanning.vcxproj
└── main-advancedMemoryForensics-Scanning.cpp
├── Chapter6_AccessingMemory
├── Chapter6_AccessingMemory.vcxproj
└── main-accessingMemory.cpp
├── Chapter7_CodeInjection
├── Chapter7_CodeInjection.vcxproj
└── main-codeInjection.cpp
├── Chapter7_CodeInjection_DLL
├── Chapter7_CodeInjection_DLL.vcxproj
├── Chapter7_CodeInjection_DLL.vcxproj.filters
└── dllmain.cpp
├── Chapter8_AdobeAirHook
├── AdobeAirHook.cpp
├── AdobeAirHook.h
├── AdobeAirHook.vcxproj
├── AdobeAirHook.vcxproj.filters
├── AdobeAirHookCallbacks.h
├── DebugConsole.cpp
├── DebugConsole.h
├── ExecutableModule.cpp
├── ExecutableModule.h
├── ThreadLock.h
└── dllmain.cpp
├── Chapter8_ControlFlow
├── CallHookExample.cpp
├── Chapter8_ControlFlow.vcxproj
├── Chapter8_ControlFlow.vcxproj.filters
├── IATHookExample.cpp
├── NOPExample.cpp
├── VFHookExample.cpp
├── main-controlFlow.cpp
└── main.h
├── Chapter8_Direct3DApplication
├── Chapter8_Direct3DApplication.vcxproj
├── Chapter8_Direct3DApplication.vcxproj.filters
└── main.cpp
├── Chapter8_Direct3DHook
├── Chapter8_Direct3DHook.vcxproj
├── Chapter8_Direct3DHook.vcxproj.filters
├── DirectXHook.cpp
├── DirectXHook.h
├── DirectXHookCallbacks.h
├── main.cpp
└── memory.h
├── GameHackingExamples.sln
├── LICENSE
├── LuaScripts
├── Chapter1_SearchingForAssemblyPatterns.lua
├── Chapter1_SearchingForStrings.lua
├── Chapter5_CountLinkedListNodes.lua
├── Chapter5_VerifyLinkedList.lua
└── Chapter5_VerifyMap.lua
├── README.md
├── allegro_linkers.h
├── arial.ttf
├── bin
├── Chapter10_ResponsiveHacks.exe
├── Chapter11_SearchAlgorithms.exe
├── Chapter11_StateMachines.exe
├── Chapter1_BasicMemory.exe
├── Chapter1_MemoryPointers.exe
├── Chapter2_BasicDebugging.exe
├── Chapter3_CloseMutex.exe
├── Chapter3_FindingFiles.exe
├── Chapter4_CodeToMemory.exe
├── Chapter5_AdvancedMemoryForensics_Scanning.exe
├── Chapter6_AccessingMemory.exe
├── Chapter7_CodeInjection.exe
├── Chapter8_ControlFlow.exe
├── Chapter8_Direct3DApplication.exe
└── DEBUG_BUILDS
│ ├── Chapter10_ResponsiveHacks.exe
│ ├── Chapter10_ResponsiveHacks.ilk
│ ├── Chapter10_ResponsiveHacks.pdb
│ ├── Chapter11_SearchAlgorithms.exe
│ ├── Chapter11_SearchAlgorithms.ilk
│ ├── Chapter11_SearchAlgorithms.pdb
│ ├── Chapter11_StateMachines.exe
│ ├── Chapter11_StateMachines.ilk
│ ├── Chapter11_StateMachines.pdb
│ ├── Chapter1_BasicMemory.exe
│ ├── Chapter1_BasicMemory.ilk
│ ├── Chapter1_BasicMemory.pdb
│ ├── Chapter1_MemoryPointers.exe
│ ├── Chapter1_MemoryPointers.ilk
│ ├── Chapter1_MemoryPointers.pdb
│ ├── Chapter2_BasicDebugging.exe
│ ├── Chapter2_BasicDebugging.ilk
│ ├── Chapter2_BasicDebugging.pdb
│ ├── Chapter3_CloseMutex.exe
│ ├── Chapter3_CloseMutex.ilk
│ ├── Chapter3_CloseMutex.pdb
│ ├── Chapter3_FindingFiles.exe
│ ├── Chapter3_FindingFiles.ilk
│ ├── Chapter3_FindingFiles.pdb
│ ├── Chapter4_CodeToMemory.exe
│ ├── Chapter4_CodeToMemory.ilk
│ ├── Chapter4_CodeToMemory.pdb
│ ├── Chapter5_AdvancedMemoryForensics_Scanning.exe
│ ├── Chapter5_AdvancedMemoryForensics_Scanning.ilk
│ ├── Chapter5_AdvancedMemoryForensics_Scanning.pdb
│ ├── Chapter6_AccessingMemory.exe
│ ├── Chapter6_AccessingMemory.ilk
│ ├── Chapter6_AccessingMemory.pdb
│ ├── Chapter7_CodeInjection.exe
│ ├── Chapter7_CodeInjection.ilk
│ ├── Chapter7_CodeInjection.pdb
│ ├── Chapter7_CodeInjection_DLL.ilk
│ ├── Chapter7_CodeInjection_DLL.pdb
│ ├── Chapter8_AdobeAirHook.ilk
│ ├── Chapter8_AdobeAirHook.pdb
│ ├── Chapter8_ControlFlow.exe
│ ├── Chapter8_ControlFlow.ilk
│ ├── Chapter8_ControlFlow.pdb
│ ├── Chapter8_Direct3DApplication.exe
│ ├── Chapter8_Direct3DApplication.ilk
│ ├── Chapter8_Direct3DApplication.pdb
│ ├── Chapter8_Direct3DHook.ilk
│ └── Chapter8_Direct3DHook.pdb
└── game.map
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled Object files
2 | *.slo
3 | *.lo
4 | *.o
5 | *.obj
6 |
7 | # Precompiled Headers
8 | *.gch
9 | *.pch
10 |
11 | # Compiled Dynamic libraries
12 | *.so
13 | *.dylib
14 | *.dll
15 |
16 | # Fortran module files
17 | *.mod
18 |
19 | # Compiled Static libraries
20 | *.lai
21 | *.la
22 | *.a
23 | *.lib
24 |
25 | # Executables
26 | *.exe
27 | *.out
28 | *.app
29 |
30 |
31 | # VS stuff
32 | *.suo
33 | *.sdf
34 | *.user
35 |
36 | #other directories
37 | */ipch/*
38 | */Debug/*
39 | */Release/*
40 | */BuildTemp/*
41 | ipch/*
42 | Debug/*
43 | Release/*
44 | BuildTemp/*
45 |
--------------------------------------------------------------------------------
/Chapter10_ResponsiveHacks/Chapter10_ResponsiveHacks.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 |
14 | {E28E3DC6-2614-43B9-83E4-86D6F9A585B1}
15 | Win32Proj
16 | Chapter10_ResponsiveHacks
17 | Chapter10_ResponsiveHacks
18 |
19 |
20 |
21 | Application
22 | true
23 | Unicode
24 |
25 |
26 | Application
27 | false
28 | true
29 | Unicode
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | true
43 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\
44 | $(SolutionDir)\bin\DEBUG_BUILDS\
45 |
46 |
47 | false
48 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\
49 | $(SolutionDir)\bin\
50 |
51 |
52 |
53 |
54 |
55 | Level3
56 | Disabled
57 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
58 | 4Bytes
59 |
60 |
61 | Console
62 | true
63 | false
64 |
65 |
66 |
67 |
68 | Level3
69 |
70 |
71 | Disabled
72 | true
73 | true
74 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
75 | 4Bytes
76 |
77 |
78 | Console
79 | true
80 | true
81 | true
82 |
83 |
84 | false
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/Chapter10_ResponsiveHacks/main-responsiveHacks.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | // WARNING: if this code is killed mid-execute or you switch to another window (not the console)
6 | // while it's executing, it may cause the system to think a modifier key is stuck.
7 | // If this happens, you can tap shift, ctrl, and alt on the LEFT side of your keyboard to "unstick it"
8 |
9 |
10 |
11 |
12 |
13 | // SendInput() example code
14 | void sendKeyWithSendInput(WORD key, bool up)
15 | {
16 | INPUT input = {0};
17 | input.type = INPUT_KEYBOARD;
18 | input.ki.wVk = key;
19 | input.ki.dwFlags = 0;
20 |
21 | if (up)
22 | input.ki.dwFlags |= KEYEVENTF_KEYUP;
23 | SendInput(1, &input, sizeof(input));
24 | }
25 |
26 | void sendModifiersWithSendInput(DWORD flags, bool up)
27 | {
28 | if (flags & 1)
29 | sendKeyWithSendInput(VK_LSHIFT, up);
30 | if (flags & 2)
31 | sendKeyWithSendInput(VK_LCONTROL, up);
32 | if (flags & 4)
33 | sendKeyWithSendInput(VK_LMENU, up);
34 | }
35 |
36 | void sendCharWithSendInput(char letter)
37 | {
38 | SHORT keyFlags = VkKeyScanA(letter);
39 |
40 | WORD key = keyFlags & 0xFF;
41 | DWORD flags = (keyFlags >> 8) & 0xFF;
42 |
43 | sendModifiersWithSendInput(flags, false);
44 |
45 | sendKeyWithSendInput(key, false);
46 | sendKeyWithSendInput(key, true);
47 |
48 | sendModifiersWithSendInput(flags, true);
49 | }
50 |
51 | void typeStringWithSendInput(const char* string)
52 | {
53 | for (int i = 0; i < strlen(string); i++)
54 | {
55 | sendCharWithSendInput(string[i]);
56 | Sleep(80);
57 | }
58 | }
59 |
60 | // SendMessage example code
61 | void sendKeyWithSendMessage(HWND window, WORD key, char letter)
62 | {
63 | SendMessageA(window, WM_KEYDOWN, key, 0);
64 | if (letter != 0)
65 | SendMessageA(window, WM_CHAR, letter, 1);
66 | SendMessageA(window, WM_KEYUP, key, 1);
67 | }
68 |
69 |
70 | void sendCharWithSendMessage(HWND window, char letter)
71 | {
72 | SHORT keyFlags = VkKeyScanA(letter);
73 |
74 | WORD key = keyFlags & 0xFF;
75 | DWORD flags = (keyFlags >> 8) & 0xFF;
76 |
77 | sendKeyWithSendMessage(window, key, letter);
78 | }
79 |
80 | void typeStringWithSendMessage(HWND window, const char* string)
81 | {
82 | for (int i = 0; i < strlen(string); i++)
83 | {
84 | sendCharWithSendMessage(window, string[i]);
85 | Sleep(80);
86 | }
87 | }
88 |
89 |
90 |
91 |
92 | DWORD WINAPI exampleThread(LPVOID lpParam)
93 | {
94 | Sleep(500);
95 | typeStringWithSendInput("Typing using SendInput()!\rHow does it look? :)\r\r");
96 |
97 | auto window = FindWindowA(NULL, "Chapter10 Input Example");
98 | typeStringWithSendMessage(window, "Typing using SendMessage()!\rEffectively the same, but more powerful :-)\r\r");
99 |
100 | std::cout << std::endl << std::endl << "DONE! you can close this now!" << std::endl;
101 |
102 | return 0;
103 | }
104 |
105 |
106 | int main(void)
107 | {
108 | std::cout << "WARNING: Don't switch between windows until this application is done typing" << std::endl;
109 | system("pause");
110 | std::cout << "Everything below here is being programmatically typed using the keyboard" << std::endl << std::endl;
111 |
112 | SetConsoleTitleA("Chapter10 Input Example");
113 |
114 | CreateThread(NULL, 0, exampleThread, 0, 0, NULL);
115 |
116 | char temp;
117 | while (true) {
118 | std::cin >> temp;
119 | }
120 | }
--------------------------------------------------------------------------------
/Chapter11_SearchAlgorithms/Chapter11_SearchAlgorithms.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #include "WindowCode.h"
9 |
10 |
11 | #define TILE_COST 1
12 |
13 | class AStarNode;
14 | typedef std::shared_ptr AStarNodePtr;
15 |
16 | class AStarNode
17 | {
18 | public:
19 | int x, y;
20 | int g, score;
21 | AStarNodePtr parent;
22 |
23 | AStarNode(int x, int y, int cost, AStarNodePtr p, int score = 0)
24 | : x(x), y(y), g(cost), score(score), parent(p)
25 | {}
26 | static AStarNodePtr makePtr(int x, int y, int cost, AStarNodePtr p, int score = 0)
27 | {
28 | return AStarNodePtr(new AStarNode(x, y, cost, p, score));
29 | }
30 | int heuristic(const int destx, int desty) const
31 | {
32 | int xd = destx - x;
33 | int yd = desty - y;
34 | return abs(xd) + abs(yd);
35 | }
36 | void updateScore(int endx, int endy)
37 | {
38 | auto h = this->heuristic(endx, endy) * TILE_COST;
39 | this->score = g + h;
40 | }
41 | AStarNodePtr getCopy()
42 | {
43 | return AStarNode::makePtr(x, y, g, parent, score);
44 | }
45 | std::vector getChildren(int width, int height)
46 | {
47 | std::vector ret;
48 | auto copy = getCopy();
49 | if (x > 0)
50 | ret.push_back(AStarNode::makePtr(x - 1, y, g + TILE_COST, copy));
51 | if (y > 0)
52 | ret.push_back(AStarNode::makePtr(x, y - 1, g + TILE_COST, copy));
53 | if (x < width - 1)
54 | ret.push_back(AStarNode::makePtr(x + 1, y, g + TILE_COST, copy));
55 | if (y < height - 1)
56 | ret.push_back(AStarNode::makePtr(x, y + 1, g + TILE_COST, copy));
57 | return ret;
58 | }
59 | };
60 |
61 | bool operator<(const AStarNodePtr &a, const AStarNodePtr &b)
62 | {
63 | return a->score > b->score;
64 | }
65 | bool operator==(const AStarNodePtr &a, const AStarNodePtr &b)
66 | {
67 | return a->x == b->x && a->y == b->y;
68 | }
69 |
70 | template
71 | void makeList(AStarNodePtr end, std::vector nodes, int path[WIDTH][HEIGHT])
72 | {
73 | for (auto n = nodes.begin(); n != nodes.end(); n++)
74 | path[(*n)->x][(*n)->y] = 2;
75 |
76 | AStarNodePtr node = end;
77 | while (node.get() != nullptr)
78 | {
79 | path[node->x][node->y] = 1;
80 | node = node->parent;
81 | }
82 | }
83 |
84 | template
85 | bool doAStarSearch(
86 | int map[WIDTH][HEIGHT],
87 | int startx, int starty,
88 | int endx, int endy,
89 | int path[WIDTH][HEIGHT])
90 | {
91 | std::priority_queue frontier;
92 | std::vector allNodes;
93 |
94 | auto node = AStarNode::makePtr(startx, starty, 0, nullptr);
95 | node->updateScore(endx, endy);
96 | allNodes.push_back(node);
97 |
98 | while (true)
99 | {
100 | if (node->x == endx && node->y == endy)
101 | {
102 | makeList(node, allNodes, path);
103 | return true;
104 | }
105 |
106 | auto children = node->getChildren(WIDTH, HEIGHT);
107 | for (auto c = children.begin(); c != children.end(); c++)
108 | {
109 | if (map[(*c)->x][(*c)->y] == BLOCKING)
110 | continue;
111 | auto found = std::find(allNodes.rbegin(), allNodes.rend(), *c);
112 | if (found != allNodes.rend())
113 | {
114 | if (*found > *c)
115 | {
116 | (*found)->g = (*c)->g;
117 | (*found)->parent = (*c)->parent;
118 | (*found)->updateScore(endx, endy);
119 | }
120 | }
121 | else
122 | {
123 | (*c)->updateScore(endx, endy);
124 | frontier.push(*c);
125 | allNodes.push_back(*c);
126 | }
127 | }
128 |
129 | if (frontier.size() == 0)
130 | return false;
131 |
132 | node = frontier.top();
133 | frontier.pop();
134 | }
135 | }
136 |
137 |
138 |
139 | int main (int argc, char *argv[])
140 | {
141 | searchFunction = doAStarSearch;
142 | showWindow();
143 | return 0;
144 | }
--------------------------------------------------------------------------------
/Chapter11_SearchAlgorithms/Chapter11_SearchAlgorithms.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 |
14 | {35470A34-CBB0-41D1-A54B-E1CF3DE9A3B7}
15 | Chapter11_SearchAlgorithms
16 |
17 |
18 |
19 | Application
20 | true
21 | Unicode
22 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\
23 | $(SolutionDir)\bin\DEBUG_BUILDS\
24 |
25 |
26 | Application
27 | false
28 | true
29 | Unicode
30 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\
31 | $(SolutionDir)\bin\
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | Level3
47 | Disabled
48 |
49 |
50 | true
51 |
52 |
53 |
54 |
55 | Level3
56 | MaxSpeed
57 | true
58 | true
59 |
60 |
61 | true
62 | true
63 | true
64 | Console
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/Chapter11_SearchAlgorithms/Chapter11_SearchAlgorithms.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hpp;hxx;hm;inl;inc;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 | Source Files
23 |
24 |
25 |
26 |
27 | Header Files
28 |
29 |
30 | Header Files
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Chapter11_SearchAlgorithms/DummyWindow.cpp:
--------------------------------------------------------------------------------
1 | #include "DummyWindow.h"
2 |
3 | /*
4 | THIS CODE EXISTS ONLY TO DISPLAY A WINDOW,
5 | AND IS NOT RELEVANT TO THE EXAMPLE CODE
6 | */
7 |
8 | std::map DummyWindow::windowMap;
9 |
10 | DummyWindow::DummyWindow(HINSTANCE _instance) : windowHandle(NULL), instance(_instance)
11 | {}
12 |
13 | DummyWindow::~DummyWindow(void)
14 | {
15 | DummyWindow::unregisterWindow(this, this->windowHandle);
16 | }
17 |
18 | bool DummyWindow::initialize()
19 | {
20 | WNDCLASSEX wcex;
21 | wcex.cbSize = sizeof(WNDCLASSEX);
22 | wcex.style = CS_HREDRAW | CS_VREDRAW;
23 | wcex.lpfnWndProc = WndProc;
24 | wcex.cbClsExtra = 0;
25 | wcex.cbWndExtra = 0;
26 | wcex.hInstance = this->instance;
27 | wcex.hIcon = NULL; //LoadIcon(this->instance, MAKEINTRESOURCE(IDI_APPLICATION));
28 | wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
29 | wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
30 | wcex.lpszMenuName = NULL;
31 | wcex.lpszClassName = L"gamhakwind";
32 | wcex.hIconSm = NULL; //LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
33 |
34 | if (!RegisterClassEx(&wcex))
35 | {
36 | auto err = GetLastError();
37 | return false;
38 | }
39 |
40 | this->windowHandle = CreateWindowA
41 | (
42 | "gamhakwind",
43 | "Game Hacking - Chapter 11 - SearchAlgorithms",
44 | WS_OVERLAPPEDWINDOW,
45 | CW_USEDEFAULT, CW_USEDEFAULT,
46 | 420, 490,
47 | NULL,
48 | NULL,
49 | this->instance,
50 | NULL
51 | );
52 | if (this->windowHandle == NULL)
53 | {
54 | auto err = GetLastError();
55 | //return false;
56 | }
57 |
58 | DummyWindow::registerWindow(this, this->windowHandle);
59 |
60 | SetTimer(this->windowHandle, NULL, 50, NULL);
61 |
62 | ShowWindow(this->windowHandle, SW_SHOW);
63 | UpdateWindow(this->windowHandle);
64 | return true;
65 | }
66 |
67 | void DummyWindow::finalize()
68 | {
69 | this->callbackMap.clear();
70 | }
71 |
72 | int32_t DummyWindow::doMessageLoop()
73 | {
74 | MSG msg;
75 | while (GetMessage(&msg, NULL, 0, 0))
76 | {
77 | TranslateMessage(&msg);
78 | DispatchMessage(&msg);
79 | }
80 | return static_cast(msg.wParam);
81 | }
82 |
83 | void DummyWindow::setMessageHandler(UINT message, windowMessageCallbackType callback)
84 | {
85 | this->callbackMap[message] = callback;
86 | }
87 |
88 | LRESULT DummyWindow::onMessageReceived(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
89 | {
90 | auto found = this->callbackMap.find(message);
91 | if (found != this->callbackMap.end())
92 | return found->second(this, message, wparam, lparam);
93 | return DefWindowProc(window, message, wparam, lparam);
94 | }
95 |
96 | void DummyWindow::registerWindow(DummyWindow* dummy, HWND window)
97 | {
98 | DummyWindow::windowMap[window] = dummy;
99 | }
100 | void DummyWindow::unregisterWindow(DummyWindow* dummy, HWND window)
101 | {
102 | auto found = DummyWindow::windowMap.find(window);
103 | if (found != DummyWindow::windowMap.end())
104 | DummyWindow::windowMap.erase(found);
105 | }
106 | DummyWindow* DummyWindow::findWindow(HWND window)
107 | {
108 | auto found = DummyWindow::windowMap.find(window);
109 | if (found != DummyWindow::windowMap.end())
110 | return found->second;
111 | return nullptr;
112 | }
113 |
114 | LRESULT DummyWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
115 | {
116 | auto dummy = DummyWindow::findWindow(hWnd);
117 | if (dummy)
118 | return dummy->onMessageReceived(hWnd, uMsg, wParam, lParam);
119 | return DefWindowProc(hWnd, uMsg, wParam, lParam);
120 | }
--------------------------------------------------------------------------------
/Chapter11_SearchAlgorithms/DummyWindow.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | /*
4 | THIS CODE EXISTS ONLY TO DISPLAY A WINDOW,
5 | AND IS NOT RELEVANT TO THE EXAMPLE CODE
6 | */
7 |
8 | #include
9 | #include
10 | #include