{"id":2386,"date":"2026-09-04T10:34:18","date_gmt":"2026-09-04T10:34:18","guid":{"rendered":"https:\/\/wayhope.kro.kr\/?p=2386"},"modified":"2026-09-06T19:58:49","modified_gmt":"2026-09-06T19:58:49","slug":"focuschecker-%ea%b0%9c%eb%b0%9c-%ed%9a%8c%ea%b3%a0","status":"publish","type":"post","link":"https:\/\/wayhope.kro.kr\/?p=2386","title":{"rendered":"FocusChecker \uac1c\ubc1c \ud68c\uace0 #Win32"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\">FocusChecker \uac1c\ubc1c \ud68c\uace0<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">FocusChecker\ub97c \ub9cc\ub4e0 \uc774\uc720<\/h2>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"189\" height=\"156\" src=\"https:\/\/wayhope.kro.kr\/wp-content\/uploads\/2026\/09\/image-18-edited.png\" alt=\"\" class=\"wp-image-2389\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">FocusChecker\ub294 PC\uc5d0\uc11c \uc791\uc5c5\ud560 \ub54c \ub0b4\uac00 \uc2e4\uc81c\ub85c \uc9d1\uc911\ud558\uace0 \uc788\ub294\uc9c0\ub97c \ud655\uc778\ud558\ub824\uace0 \ub9cc\ub4e0 \ud504\ub85c\uadf8\ub7a8\uc774\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ucc98\uc74c\ubd80\ud130 \uc9d1\uc911\ub3c4\ub97c \uc815\uad50\ud558\uac8c \ubd84\uc11d\ud558\ub824\ub358 \uac83\uc740 \uc544\ub2c8\ub2e4. \uce74\uba54\ub77c\ub97c \uc4f0\uac70\ub098 \ubcc4\ub3c4\uc758 \uba38\uc2e0\ub7ec\ub2dd \ubaa8\ub378\uc744 \ubd99\uc774\ub294 \uac83\ub3c4 \uc0dd\uac01\ud558\uc9c0 \uc54a\uc558\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud0a4\ubcf4\ub4dc\ub97c \uc785\ub825\ud558\uace0 \uc788\ub294\uc9c0, \ub9c8\uc6b0\uc2a4\ub97c \uc6c0\uc9c1\uc774\uace0 \uc788\ub294\uc9c0, \ud720\uc744 \uc0ac\uc6a9\ud558\uace0 \uc788\ub294\uc9c0 \uc815\ub3c4\ub9cc \ud655\uc778\ud574\ub3c4 \ub300\ub7b5\uc801\uc778 \ud65c\ub3d9 \uc0c1\ud0dc\ub294 \uc54c \uc218 \uc788\ub2e4\uace0 \ubd24\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc5ec\uae30\uc5d0 \uc57d\uac04\uc758 \uac8c\uc784 \uc694\uc18c\ub97c \ub123\uc5c8\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud65c\ub3d9\uc744 \ud558\uace0 \uc788\uc73c\uba74 Point\uac00 \uc62c\ub77c\uac04\ub2e4. \uc77c\uc815 \uc2dc\uac04 \uc544\ubb34\ub7f0 \uc785\ub825\uc774 \uc5c6\uc73c\uba74 Point\uac00 \ub5a8\uc5b4\uc9c4\ub2e4. Point\uac00 \ubaa8\ub450 \ub5a8\uc5b4\uc9c0\uba74 \ud604\uc7ac \uc7ac\uc0dd \uc911\uc778 \ubbf8\ub514\uc5b4\ub97c \uc815\uc9c0\uc2dc\ud0a8\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub9ac\uace0 \uc774 Point\ub97c \uadf8\ub0e5 \ud504\ub85c\uadf8\ub7a8 \uc548\uc5d0\uc11c\ub9cc \uc0ac\uc6a9\ud558\ub294 \uac8c \uc544\ub2c8\ub77c \uae30\uc874\uc5d0 \ub9cc\ub4e4\uc5c8\ub358 Tack TODO\uc640 \uc5f0\uacb0\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Tack TODO\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 Firebase \uacc4\uc815\uc744 FocusChecker\uc5d0\uc11c\ub3c4 \uadf8\ub300\ub85c \uc0ac\uc6a9\ud558\uace0, \uc9d1\uc911 \uc138\uc158\uc774 \ub05d\ub098\uba74 \uacc4\uc0b0\ub41c Coin\uc744 Firestore\uc5d0 \uc9c0\uae09\ud558\ub294 \ubc29\uc2dd\uc774\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uacb0\uacfc\uc801\uc73c\ub85c \ub450 \ud504\ub85c\uadf8\ub7a8\uc774 \uc11c\ub85c \ub2e4\ub978 \uae30\uc220\ub85c \ub9cc\ub4e4\uc5b4\uc84c\uc9c0\ub9cc \ud558\ub098\uc758 \uacc4\uc815\uc744 \uacf5\uc720\ud558\uac8c \ub410\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Flutter\ub85c \ub9cc\ub4e4\uc9c0 \uc54a\uc740 \uc774\uc720<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Tack TODO\uac00 Flutter\ub85c \ub9cc\ub4e4\uc5b4\uc838 \uc788\uc5b4\uc11c \ucc98\uc74c\uc5d0\ub294 FocusChecker\ub3c4 Flutter\ub85c \ub9cc\ub4e4\uae4c \uc0dd\uac01\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub7f0\ub370 \uc694\uad6c\uc0ac\ud56d\uc744 \ub193\uace0 \ubcf4\ub2c8 \uad73\uc774 \uadf8\ub7f4 \uc774\uc720\uac00 \uc5c6\uc5c8\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">FocusChecker\uc5d0\uc11c \ud544\uc694\ud55c \ud654\uba74\uc740 \ud06c\uc9c0 \uc54a\ub2e4. \ubc18\uba74 \ud504\ub85c\uadf8\ub7a8\uc740 \uacc4\uc18d \ucf1c\uc838 \uc788\uc73c\uba74\uc11c \ud0a4\ubcf4\ub4dc\uc640 \ub9c8\uc6b0\uc2a4 \uc785\ub825\uc744 \uac10\uc9c0\ud574\uc57c \ud55c\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Windows API\ub97c \uc9c1\uc811 \uc0ac\uc6a9\ud558\ub294 \ubd80\ubd84\ub3c4 \ub9ce\uc558\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub798\uc11c C++20\uacfc Win32 API\ub85c \ub9cc\ub4e4\uc5c8\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">UI\ub294 GDI\ub85c \uadf8\ub838\uace0 \ub124\ud2b8\uc6cc\ud06c\ub294 WinHTTP\ub97c \uc0ac\uc6a9\ud588\ub2e4. Google \ub85c\uadf8\uc778 \ud654\uba74\ub9cc WebView2\ub97c \ub123\uc5c8\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Firebase C++ SDK\ub3c4 \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uc558\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc774\uac78 \ub123\uc73c\uba74 gRPC, Protobuf, OpenSSL \uac19\uc740 \uc758\uc874\uc131\uc774 \uac19\uc774 \ub530\ub77c\uc628\ub2e4. FocusChecker\uc5d0\uc11c Firebase\ub97c \uc0ac\uc6a9\ud558\ub294 \ubaa9\uc801\uc740 \ubcf5\uc7a1\ud55c \uae30\ub2a5\uc774 \uc544\ub2c8\ub77c \uc778\uc99d\uacfc Firestore \ub370\uc774\ud130 \uc811\uadfc \uc815\ub3c4\uc600\uae30 \ub54c\ubb38\uc5d0 \uc774 \uc815\ub3c4 \uc758\uc874\uc131\uc744 \uac00\uc838\uc624\ub294 \uac8c \ub9c8\uc74c\uc5d0 \ub4e4\uc9c0 \uc54a\uc558\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uacb0\uad6d \ud544\uc694\ud55c API\ub9cc REST\ub85c \ud638\ucd9c\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Win32 + WinHTTP + WebView2 \uc815\ub3c4\uba74 \ud544\uc694\ud55c \uae30\ub2a5\uc744 \ub9cc\ub4e4 \uc218 \uc788\uc5c8\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\uc785\ub825\uc744 \uc5b4\ub5bb\uac8c \ud65c\ub3d9\uc73c\ub85c \ubcfc \uac83\uc778\uac00<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\ud0a4\ubcf4\ub4dc\uc640 \ub9c8\uc6b0\uc2a4\ub97c \uac10\uc9c0\ud558\ub294 \uac83 \uc790\uccb4\ub294 \uc5b4\ub835\uc9c0 \uc54a\uc558\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ubb38\uc81c\ub294 \uc5b4\ub514\uae4c\uc9c0\ub97c \ud65c\ub3d9\uc73c\ub85c \uc778\uc815\ud560 \uac83\uc778\uac00\uc600\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc608\ub97c \ub4e4\uc5b4 \ub9c8\uc6b0\uc2a4\uac00 1~2px \uc6c0\uc9c1\uc600\ub2e4\uace0 \ud574\uc11c \uc0ac\uc6a9\uc790\uac00 \uc2e4\uc81c\ub85c \uc791\uc5c5\ud588\ub2e4\uace0 \ubcf4\uae30\ub294 \uc5b4\ub835\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub300\ub85c Point\ub97c \uc9c0\uae09\ud558\uba74 \ub9c8\uc6b0\uc2a4\ub97c \uc0b4\uc9dd \ud754\ub4dc\ub294 \uac83\ub9cc\uc73c\ub85c \uacc4\uc18d \uc810\uc218\ub97c \uc5bb\uc744 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub798\uc11c \ub9c8\uc6b0\uc2a4 \uc774\ub3d9\ub7c9\uc5d0 \uc784\uacc4\uac12\uc744 \ub123\uc5c8\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>double distance = std::sqrt(dx * dx + dy * dy);\n\nif (distance &gt;= MOUSE_MOVE_THRESHOLD_PX &amp;&amp;\n    sinceLastGain &gt;= MOUSE_MOVE_POINT_COOLDOWN_MS) {\n    lastMousePos = currentPos;\n    lastMousePointGain = now;\n    return true;\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\ud604\uc7ac\ub294 30px \uc774\uc0c1 \uc6c0\uc9c1\uc600\uc744 \ub54c\ub9cc \uc774\ub3d9\uc744 \uc778\uc815\ud558\uace0, \ud55c \ubc88 Point\ub97c \uc5bb\uc740 \ub4a4\uc5d0\ub294 450ms\uc758 \ucfe8\ub2e4\uc6b4\uc744 \ub454\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud0a4\ubcf4\ub4dc\ub294 \ub610 \ub2e4\ub978 \ubb38\uc81c\uac00 \uc788\uc5c8\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>GetAsyncKeyState()<\/code>\ub97c \uadf8\ub0e5 \uc0ac\uc6a9\ud558\uba74 \ud0a4\ub97c \uacc4\uc18d \ub204\ub974\uace0 \uc788\ub294 \ub3d9\uc548\uc5d0\ub3c4 \ub20c\ub9bc \uc0c1\ud0dc\uac00 \uacc4\uc18d \uc7a1\ud78c\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub7ec\uba74 \ud0a4 \ud558\ub098\ub97c \ub204\ub974\uace0 \uc788\ub294 \uac83\ub9cc\uc73c\ub85c \ud65c\ub3d9\uc774 \uacc4\uc18d \ubc1c\uc0dd\ud55c\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub798\uc11c <code>keyHeld<\/code>\uc5d0 \uc774\uc804 \uc0c1\ud0dc\ub97c \uc800\uc7a5\ud558\uace0 \uc2e4\uc81c\ub85c \ub20c\ub9ac\ub294 \uc21c\uac04\ub9cc \ucc98\ub9ac\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud720\uc740 <code>WH_MOUSE_LL<\/code> \ud6c5\uc73c\ub85c \ub530\ub85c \ubc1b\uc558\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc774 \ubd80\ubd84\uc744 UI \uc2a4\ub808\ub4dc\uc5d0\uc11c \uc9c1\uc811 \ucc98\ub9ac\ud558\uba74 \uba54\uc2dc\uc9c0\uac00 \ubc00\ub9b4 \ub54c \ub9c8\uc6b0\uc2a4 \ubc18\uc751\uc5d0 \uc601\ud5a5\uc744 \uc904 \uc218 \uc788\uc5b4\uc11c \ubcc4\ub3c4 \uc2a4\ub808\ub4dc\ub85c \ubd84\ub9ac\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud720 \uc774\ubca4\ud2b8\uac00 \ub4e4\uc5b4\uc624\uba74 \ubc14\ub85c UI\ub97c \uac74\ub4dc\ub9ac\uc9c0 \uc54a\uace0 <code>atomic<\/code> \ubcc0\uc218\uc5d0 \uae30\ub85d\ud55c\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if (wheelMoved.exchange(false)) {\n    ++activityCount;\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">UI \ucabd\uc5d0\uc11c\ub294 \ud544\uc694\ud55c \uc2dc\uc810\uc5d0 \uc774 \uac12\uc744 \ud655\uc778\ud55c\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc785\ub825 \uac10\uc9c0 \uc790\uccb4\ubcf4\ub2e4 \uacc4\uc18d \uc2e4\ud589\ub418\ub294 \ud504\ub85c\uadf8\ub7a8\uc5d0\uc11c \uc785\ub825\uc744 \uc5b4\ub5bb\uac8c \uc18c\ube44\ud560\uc9c0\ub97c \uc815\ud558\ub294 \ucabd\uc774 \ub354 \uc2e0\uacbd \uc4f0\uc600\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Point \uac10\uc18c \ubc29\uc2dd\uc744 \ubc14\uafbc \uc774\uc720<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\ucc98\uc74c\uc5d0\ub294 \uc77c\uc815 \uc2dc\uac04\uc774 \uc9c0\ub098\uba74 \uc77c\uc815\ub7c9\uc758 Point\ub97c \ube7c\ub294 \ubc29\uc2dd\ub3c4 \uc0dd\uac01\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub7f0\ub370 10\ucd08 \uc815\ub3c4 \uc26c\ub294 \uac83\uacfc \uba87 \ubd84 \ub3d9\uc548 \uc544\ubb34\uac83\ub3c4 \ud558\uc9c0 \uc54a\ub294 \uac83\uc744 \ub611\uac19\uc774 \ucc98\ub9ac\ud558\ub294 \uac8c \uc774\uc0c1\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub798\uc11c \uc720\ud734 \uc2dc\uac04\uc774 \uae38\uc5b4\uc9c8\uc218\ub85d \uac10\uc18c\ub7c9\uc774 \ucee4\uc9c0\ub294 \ud615\ud0dc\ub85c \ub9cc\ub4e4\uc5c8\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Decay(x) = floor(x * Rate + Base)\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uc5ec\uae30\uc11c <code>x<\/code>\ub294 \ub9c8\uc9c0\ub9c9\uc73c\ub85c Point\ub97c \uc5bb\uc740 \ub4a4 \uc9c0\ub098\uac04 \uc2dc\uac04\uc774\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc7a0\uae50 \uc26c\uc5c8\uc744 \ub54c\ub294 \uac10\uc18c\uac00 \uc791\uace0, \uc624\ub798 \uc790\ub9ac\ub97c \ube44\uc6b0\uba74 \ub354 \ube60\ub974\uac8c \ub5a8\uc5b4\uc9c4\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Point\uac00 0\uc774 \ub418\uc5c8\uc744 \ub54c\ub294 \uadf8\ub0e5 \ud654\uba74\uc5d0 \uacbd\uace0\ub9cc \ud45c\uc2dc\ud558\uc9c0 \uc54a\uc558\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud604\uc7ac \uc7ac\uc0dd \uc911\uc778 \ubbf8\ub514\uc5b4\ub97c \uc815\uc9c0\uc2dc\ucf30\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Windows\uc758 <code>VK_MEDIA_PLAY_PAUSE<\/code> \ud0a4 \uc774\ubca4\ud2b8\ub97c \ubc1c\uc0dd\uc2dc\ud0a4\ub294 \ubc29\uc2dd\uc774\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if (point == 0 &amp;&amp; !isStoped) {\n    SimulatePlayStopKey();\n    isStoped = true;\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uc774 \uae30\ub2a5 \ub54c\ubb38\uc5d0 Point\ub97c \ub2e8\uc21c\ud55c \uc810\uc218\ubcf4\ub2e4\ub294 \uc9d1\uc911 \uc0c1\ud0dc\ub97c \uc720\uc9c0\ud558\uae30 \uc704\ud55c \uc5ec\uc720\ubd84\uc5d0 \uac00\uae5d\uac8c \uc0ac\uc6a9\ud558\uac8c \ub410\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Google \ub85c\uadf8\uc778\uc744 Win32 \ud504\ub85c\uadf8\ub7a8 \uc548\uc5d0\uc11c \ucc98\ub9ac\ud558\uae30<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">FocusChecker\ub294 Tack TODO\uc640 \uac19\uc740 Firebase \uacc4\uc815\uc744 \uc0ac\uc6a9\ud574\uc57c \ud55c\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub798\uc11c \ud504\ub85c\uadf8\ub7a8 \uc548\uc5d0\uc11c Google \ub85c\uadf8\uc778\uc744 \ucc98\ub9ac\ud560 \ud544\uc694\uac00 \uc788\uc5c8\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ucc98\uc74c \uc0dd\uac01\ud55c \ubc29\ubc95\uc740 \uc678\ubd80 \ube0c\ub77c\uc6b0\uc800\ub97c \uc5f4\uace0 callback\uc744 \ubc1b\ub294 \ubc29\uc2dd\uc774\uc5c8\ub2e4. \uadf8\ub7f0\ub370 \uc791\uc740 \uc720\ud2f8\ub9ac\ud2f0 \ud558\ub098 \ub54c\ubb38\uc5d0 localhost callback \uc11c\ubc84\uae4c\uc9c0 \ub530\ub85c \ub9cc\ub4dc\ub294 \uac74 \uacfc\ud558\ub2e4\uace0 \uc0dd\uac01\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub798\uc11c WebView2\ub97c \ub123\uc5c8\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub7f0\ub370 Google \ub85c\uadf8\uc778 \ud398\uc774\uc9c0\uc5d0\uc11c \ubc14\ub85c \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">WebView2\uc758 \uae30\ubcf8 User-Agent\ub85c \uc811\uadfc\ud558\uba74 <code>403 disallowed_useragent<\/code>\uac00 \ubc1c\uc0dd\ud588\ub2e4. Google \ucabd\uc5d0\uc11c \uc784\ubca0\ub514\ub4dc \uc6f9\ubdf0\uc758 \ub85c\uadf8\uc778 \ubc29\uc2dd\uc744 \uc81c\ud55c\ud558\uace0 \uc788\uc5c8\uae30 \ub54c\ubb38\uc774\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub798\uc11c WebView2\uc758 User-Agent\ub97c \ub370\uc2a4\ud06c\ud1b1 Chrome \ud615\ud0dc\ub85c \ubcc0\uacbd\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub9ac\uace0 <code>NavigationStarting<\/code> \uc774\ubca4\ud2b8\uc5d0\uc11c \ud604\uc7ac \uc774\ub3d9\ud558\ub824\ub294 URL\uc744 \ud655\uc778\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Firebase Auth Handler\ub85c \uc774\ub3d9\ud558\ub294 \uc21c\uac04 URL Fragment\uc5d0 \ub4e4\uc5b4\uc788\ub294 \uc778\uc99d \uc815\ubcf4\ub97c \uac00\uc838\uc624\uace0 \ud574\ub2f9 Navigation\uc740 \ucde8\uc18c\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ubcc4\ub3c4\uc758 callback \uc11c\ubc84 \uc5c6\uc774 WebView2 \uc548\uc5d0\uc11c \uc778\uc99d \uacb0\uacfc\ub97c \uac00\uc838\uc624\ub294 \ubc29\uc2dd\uc774\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc774\ucabd\uc740 \ucf54\ub4dc\ubcf4\ub2e4 WebView2\uc640 Google \ub85c\uadf8\uc778 \uc0ac\uc774\uc5d0\uc11c \uc5b4\ub5a4 \ubd80\ubd84\uc774 \ub9c9\ud788\ub294\uc9c0 \ud655\uc778\ud558\ub294 \ub370 \uc2dc\uac04\uc774 \ub354 \uac78\ub838\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Firebase C++ SDK \ub300\uc2e0 REST API \uc0ac\uc6a9<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\ub85c\uadf8\uc778\uc774 \ub05d\ub098\uba74 \uc9d1\uc911 \uc138\uc158\uc774 \uc885\ub8cc\ub420 \ub54c Coin\uc744 \uc9c0\uae09\ud574\uc57c \ud55c\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc5ec\uae30\uc11c Firebase C++ SDK\ub97c \ub123\ub294 \ub300\uc2e0 WinHTTP\ub85c Firestore REST API\ub97c \ud638\ucd9c\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud544\uc694\ud55c \uac74 \ub9ce\uc9c0 \uc54a\uc558\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud604\uc7ac \uc778\uc99d\ub41c \uc0ac\uc6a9\uc790\uc758 \ub370\uc774\ud130\ub97c \uc77d\uace0, Coin\uc744 \uc99d\uac00\uc2dc\ud0a4\uace0, \ud544\uc694\ud55c \uac12\uc744 \uac00\uc838\uc624\ub294 \uc815\ub3c4\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub798\uc11c HTTP \uc694\uccad\uc744 \uc9c1\uc811 \ub9cc\ub4dc\ub294 \ucabd\uc744 \uc120\ud0dd\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Coin \uc9c0\uae09\uc5d0\uc11c \ud2b9\ud788 \uc2e0\uacbd \uc4f4 \uac83\uc740 \uc99d\uac00 \ubc29\uc2dd\uc774\uc5c8\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud604\uc7ac Coin\uc744 \uc77d\uc5b4\uc11c <code>+1<\/code>\ud55c \ub2e4\uc74c \ub2e4\uc2dc \uc800\uc7a5\ud558\uba74 \ub3d9\uc2dc \uc694\uccad\uc5d0\uc11c \ubb38\uc81c\uac00 \uc0dd\uae34\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc608\ub97c \ub4e4\uc5b4 \ud604\uc7ac Coin\uc774 100\uc77c \ub54c \ub450 \uc694\uccad\uc774 \ub3d9\uc2dc\uc5d0 100\uc744 \uc77d\uc73c\uba74 \ub458 \ub2e4 101\uc744 \uc800\uc7a5\ud560 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ub450 \ubc88 \uc9c0\uae09\ud588\ub294\ub370 \uacb0\uacfc\uac00 101\uc774 \ub41c\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub798\uc11c Firestore\uc758 <code>increment<\/code>\ub97c \uc0ac\uc6a9\ud588\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\"updateTransforms\": &#91;{\n    \"fieldPath\": \"coins\",\n    \"increment\": {\n        \"integerValue\": \"...\"\n    }\n}]\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">\uac12\uc744 \uc77d\uace0 \uacc4\uc0b0\ud574\uc11c \ub36e\uc5b4\uc4f0\ub294 \uac8c \uc544\ub2c8\ub77c Firestore\uc5d0\uc11c \uc99d\uac00 \uc5f0\uc0b0\uc744 \ucc98\ub9ac\ud558\ub3c4\ub85d \ud588\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\uc774\uc804 \uc138\uc158\uc758 \uc751\ub2f5\uc774 \uc0c8 \uc138\uc158\uc744 \uac74\ub4dc\ub9ac\ub294 \ubb38\uc81c<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">\uc5ec\uae30\uc11c \ud55c \ubc88 \ubb38\uc81c\uac00 \ud130\uc84c\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc9d1\uc911 \uc138\uc158\uc744 \uc885\ub8cc\ud558\uba74 Coin \uc9c0\uae09 \uc694\uccad\uc744 \ubcc4\ub3c4\uc758 \uc6cc\ucee4 \uc2a4\ub808\ub4dc\uc5d0\uc11c \ucc98\ub9ac\ud55c\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">HTTP \uc694\uccad\uc774 \ubc14\ub85c \ub05d\ub098\ub294 \uac8c \uc544\ub2c8\uae30 \ub54c\ubb38\uc5d0 \uc0ac\uc6a9\uc790\uac00 \uadf8 \uc0ac\uc774\uc5d0 \ub2e4\uc2dc \uc9d1\uc911\uc744 \uc2dc\uc791\ud560 \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc0c1\ud669\uc740 \ub300\ub7b5 \uc774\ub807\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc138\uc158 A \uc885\ub8cc -&gt; Coin \uc694\uccad \uc804\uc1a1 -&gt; \uc138\uc158 B \uc2dc\uc791 -&gt; A \uc694\uccad \uc751\ub2f5 \ub3c4\ucc29<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A\uc758 \uc751\ub2f5\uc774 \ub2a6\uac8c \ub4e4\uc5b4\uc654\ub294\ub370 UI\uc5d0\uc11c\ub294 \ud604\uc7ac B\uac00 \uc9c4\ud589 \uc911\uc774\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub7f0\ub370 A\uc758 \uc751\ub2f5\uc744 \uadf8\ub0e5 \ubc18\uc601\ud558\uba74 B\uc758 \uc0c1\ud0dc\ub97c A\uc758 \uacb0\uacfc\uac00 \ub36e\uc5b4\uc4f0\uac8c \ub41c\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ucc98\uc74c\uc5d0\ub294 UI \uc0c1\ud0dc \uad00\ub9ac \ubb38\uc81c\uc778 \uc904 \uc54c\uc558\ub294\ub370 \ub85c\uadf8\ub97c \ucc0d\uc5b4\ubcf4\ub2c8 \uc774\uc804 \uc138\uc158\uc758 \uc751\ub2f5\uc774 \ub2a6\uac8c \ub4e4\uc5b4\uc624\ub294 \uac8c \uc6d0\uc778\uc774\uc5c8\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub798\uc11c \uc138\uc158\ub9c8\ub2e4 ID\ub97c \ud558\ub098\uc529 \ubd80\uc5ec\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>g_focusSessionId<\/code>\ub97c \uc99d\uac00\uc2dc\ud0a4\uace0 \uc6cc\ucee4\uc5d0\uc11c UI\ub85c \uacb0\uacfc\ub97c \uc804\ub2ec\ud560 \ub54c \ud604\uc7ac \uc138\uc158 ID\ub3c4 \uac19\uc774 \ubcf4\ub0b8\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const WPARAM packed =\n    (static_cast&lt;uint64_t&gt;(sessionId) &lt;&lt; 1) | (ok ? 1u : 0u);\n\nPostMessage(\n    hwnd,\n    WM_COIN_AWARDED,\n    packed,\n    earnedCoin\n);\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">UI\uc5d0\uc11c\ub294 \uc804\ub2ec\ubc1b\uc740 \uc138\uc158 ID\uc640 \ud604\uc7ac \uc138\uc158 ID\uac00 \uac19\uc740 \uacbd\uc6b0\uc5d0\ub9cc \uacb0\uacfc\ub97c \ubc18\uc601\ud55c\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uacb0\uacfc\uc801\uc73c\ub85c \uc608\uc804\uc5d0 \uc2dc\uc791\ud588\ub358 \uc694\uccad\uc774 \ub4a4\ub2a6\uac8c \ub3cc\uc544\uc640\ub3c4 \ud604\uc7ac \uc138\uc158\uc744 \uac74\ub4dc\ub9ac\uc9c0 \ubabb\ud558\uac8c \ub410\ub2e4.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Win32 UI\ub97c \uc9c1\uc811 \ub9cc\ub4e4\uba74\uc11c \uc0dd\uae34 \ubb38\uc81c<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">UI\ub294 \ucd5c\ub300\ud55c \uc791\uac8c \ub9cc\ub4e4 \uc0dd\uac01\uc774\uc5c8\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub798\uc11c \ubcc4\ub3c4\uc758 UI \ud504\ub808\uc784\uc6cc\ud06c\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\uace0 GDI\ub85c \uc9c1\uc811 \uadf8\ub838\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">DWM API\ub97c \uc0ac\uc6a9\ud574\uc11c \ub2e4\ud06c \ud0c0\uc774\ud2c0\ubc14\ub97c \uc801\uc6a9\ud588\uace0, \ubc84\ud2bc\ub3c4 \uc9c1\uc811 \uadf8\ub838\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uc5ec\uae30\uc11c Pin \ubaa8\ub4dc\ub97c \ucd94\uac00\ud558\uba74\uc11c \ucc3d \uc2a4\ud0c0\uc77c\uc744 \ubc14\uafe8\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud56d\uc0c1 \uc704\uc5d0 \ub744\uc6b0\ub294 \ubaa8\ub4dc\uc5d0\uc11c\ub294 \ud0c0\uc774\ud2c0\ubc14\uac00 \ud544\uc694 \uc5c6\uc5b4\uc11c <code>WS_CAPTION<\/code>\uc744 \uc81c\uac70\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub7ac\ub354\ub2c8 \ucc3d \ud06c\uae30\uac00 \ubbf8\ubb18\ud558\uac8c \ub2ec\ub77c\uc84c\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Win32\uc5d0\uc11c\ub294 Window \uc804\uccb4 \uc601\uc5ed\uacfc Client \uc601\uc5ed\uc774 \ub2e4\ub974\uae30 \ub54c\ubb38\uc774\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub798\uc11c <code>AdjustWindowRect<\/code>\ub97c \uc774\uc6a9\ud574\uc11c \ud504\ub808\uc784 \ud06c\uae30\ub97c \ub2e4\uc2dc \uacc4\uc0b0\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ub0b4\ubd80 Client \uc601\uc5ed\uc740 <code>190 x 158<\/code>\ub85c \uc720\uc9c0\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud0c0\uc774\ud2c0\ubc14\ub97c \uc5c6\uc560\uace0 \ub098\ub2c8 \ucc3d\uc744 \ub4dc\ub798\uadf8\ud560 \uc601\uc5ed\ub3c4 \uc0ac\ub77c\uc84c\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uadf8\ub798\uc11c <code>WM_NCHITTEST<\/code>\uc5d0\uc11c <code>HTCLIENT<\/code>\ub97c <code>HTCAPTION<\/code>\uc73c\ub85c \ucc98\ub9ac\ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\uacb0\uacfc\uc801\uc73c\ub85c \ucc3d \ub0b4\ubd80\ub97c \ub9c8\uc6b0\uc2a4\ub85c \uc7a1\uace0 \uc6c0\uc9c1\uc77c \uc218 \uc788\uac8c \ud588\ub2e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\ud504\ub808\uc784\uc6cc\ud06c\ub97c \uc0ac\uc6a9\ud588\ub2e4\uba74 \ud06c\uac8c \uc2e0\uacbd \uc4f0\uc9c0 \uc54a\uc558\uc744 \ubd80\ubd84\uc778\ub370 Win32\uc5d0\uc11c\ub294 \uc774\ub7f0 \uac83\uae4c\uc9c0 \uc9c1\uc811 \ucc98\ub9ac\ud574\uc57c \ud588\ub2e4.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>FocusChecker \uac1c\ubc1c \ud68c\uace0 FocusChecker\ub97c \ub9cc\ub4e0 \uc774\uc720 FocusChecker\ub294 PC\uc5d0\uc11c \uc791\uc5c5\ud560 \ub54c \ub0b4\uac00 \uc2e4\uc81c\ub85c \uc9d1\uc911\ud558\uace0 \uc788\ub294\uc9c0\ub97c \ud655\uc778\ud558\ub824\uace0 \ub9cc\ub4e0 \ud504\ub85c\uadf8\ub7a8\uc774\ub2e4. \ucc98\uc74c\ubd80\ud130 \uc9d1\uc911\ub3c4\ub97c \uc815\uad50\ud558\uac8c \ubd84\uc11d\ud558\ub824\ub358 \uac83\uc740 \uc544\ub2c8\ub2e4. \uce74\uba54\ub77c\ub97c \uc4f0\uac70\ub098 \ubcc4\ub3c4\uc758 \uba38\uc2e0\ub7ec\ub2dd \ubaa8\ub378\uc744 \ubd99\uc774\ub294 \uac83\ub3c4 \uc0dd\uac01\ud558\uc9c0 \uc54a\uc558\ub2e4. \ud0a4\ubcf4\ub4dc\ub97c \uc785\ub825\ud558\uace0 \uc788\ub294\uc9c0, \ub9c8\uc6b0\uc2a4\ub97c \uc6c0\uc9c1\uc774\uace0 \uc788\ub294\uc9c0, \ud720\uc744 \uc0ac\uc6a9\ud558\uace0 \uc788\ub294\uc9c0 \uc815\ub3c4\ub9cc \ud655\uc778\ud574\ub3c4 \ub300\ub7b5\uc801\uc778 \ud65c\ub3d9 \uc0c1\ud0dc\ub294 \uc54c \uc218 \uc788\ub2e4\uace0 \ubd24\ub2e4. \uc5ec\uae30\uc5d0 \uc57d\uac04\uc758 \uac8c\uc784 \uc694\uc18c\ub97c \ub123\uc5c8\ub2e4. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[28],"tags":[],"class_list":["post-2386","post","type-post","status-publish","format-standard","hentry","category-projects"],"_links":{"self":[{"href":"https:\/\/wayhope.kro.kr\/index.php?rest_route=\/wp\/v2\/posts\/2386","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wayhope.kro.kr\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wayhope.kro.kr\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wayhope.kro.kr\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wayhope.kro.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2386"}],"version-history":[{"count":2,"href":"https:\/\/wayhope.kro.kr\/index.php?rest_route=\/wp\/v2\/posts\/2386\/revisions"}],"predecessor-version":[{"id":2391,"href":"https:\/\/wayhope.kro.kr\/index.php?rest_route=\/wp\/v2\/posts\/2386\/revisions\/2391"}],"wp:attachment":[{"href":"https:\/\/wayhope.kro.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2386"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wayhope.kro.kr\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2386"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wayhope.kro.kr\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2386"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}