Instantly share code, notes, and snippets.
Last active
December 23, 2015 23:28
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save vabock/6709726 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2013 Vabock | |
* | |
* 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. | |
*/ | |
// ============================================================================ | |
// declarations | |
// ============================================================================ | |
// ---------------------------------------------------------------------------- | |
// headers | |
// ---------------------------------------------------------------------------- | |
// For compilers that support precompilation, includes "wx/wx.h". | |
#include "wx/wxprec.h" | |
#ifdef __BORLANDC__ | |
#pragma hdrstop | |
#endif | |
// for all others, include the necessary headers (this file is usually all you | |
// need because it includes almost all "standard" wxWidgets headers) | |
#ifndef WX_PRECOMP | |
#include "wx/wx.h" | |
#endif | |
#include "wx/regex.h" | |
// ---------------------------------------------------------------------------- | |
// private classes | |
// ---------------------------------------------------------------------------- | |
// Define a new application type, each program should derive a class from wxApp | |
class MyApp : public wxApp | |
{ | |
public: | |
// override base class virtuals | |
// ---------------------------- | |
// this one is called on application startup and is a good place for the app | |
// initialization (doing it here and not in the ctor allows to have an error | |
// return: if OnInit() returns false, the application terminates) | |
virtual bool OnInit(); | |
}; | |
// Define a new frame type: this is going to be our main frame | |
class MyFrame : public wxFrame | |
{ | |
public: | |
// ctor(s) | |
MyFrame(const wxString& title); | |
// event handlers (these functions should _not_ be virtual) | |
void OnTimer(wxTimerEvent& event); | |
void OnChar(wxKeyEvent &event); | |
void OnPaint(wxPaintEvent &event); | |
WXLRESULT MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam); | |
private: | |
wxTimer m_timer; | |
wxFont m_font; | |
wxString m_text; | |
HWND m_chromeWindow; | |
// any class wishing to process wxWidgets events must use this macro | |
DECLARE_EVENT_TABLE() | |
}; | |
// ---------------------------------------------------------------------------- | |
// constants | |
// ---------------------------------------------------------------------------- | |
// IDs for the controls and the menu commands | |
const int TIMER_ID = 1; | |
// ---------------------------------------------------------------------------- | |
// event tables and other macros for wxWidgets | |
// ---------------------------------------------------------------------------- | |
// the event tables connect the wxWidgets events with the functions (event | |
// handlers) which process them. It can be also done at run-time, but for the | |
// simple menu events like this the static method is much simpler. | |
BEGIN_EVENT_TABLE(MyFrame, wxFrame) | |
EVT_TIMER(TIMER_ID, MyFrame::OnTimer) | |
EVT_PAINT(MyFrame::OnPaint) | |
EVT_CHAR_HOOK(MyFrame::OnChar) | |
END_EVENT_TABLE() | |
// Create a new application object: this macro will allow wxWidgets to create | |
// the application object during program execution (it's better than using a | |
// static object for many reasons) and also implements the accessor function | |
// wxGetApp() which will return the reference of the right type (i.e. MyApp and | |
// not wxApp) | |
IMPLEMENT_APP(MyApp) | |
// ============================================================================ | |
// implementation | |
// ============================================================================ | |
// ---------------------------------------------------------------------------- | |
// the application class | |
// ---------------------------------------------------------------------------- | |
// 'Main program' equivalent: the program execution "starts" here | |
bool MyApp::OnInit() | |
{ | |
// call the base class initialization method, currently it only parses a | |
// few common command-line options but it could be do more in the future | |
if (!wxApp::OnInit()) { | |
return false; | |
} | |
// create the main application window | |
MyFrame *frame = new MyFrame("Minimal wxWidgets App"); | |
// and show it (the frames, unlike simple controls, are not shown when | |
// created initially) | |
frame->Show(true); | |
// success: wxApp::OnRun() will be called which will enter the main message | |
// loop and the application will run. If we returned false here, the | |
// application would exit immediately. | |
return true; | |
} | |
// ---------------------------------------------------------------------------- | |
// main frame | |
// ---------------------------------------------------------------------------- | |
// frame constructor | |
MyFrame::MyFrame(const wxString& title) | |
: wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(200, 100), | |
wxSTAY_ON_TOP | wxCLIP_CHILDREN | wxRESIZE_BORDER | wxFULL_REPAINT_ON_RESIZE | wxFRAME_NO_TASKBAR), | |
m_font(20, wxDEFAULT, wxNORMAL, wxNORMAL, false, wxT("Comic Sans MS")), m_chromeWindow(0), | |
m_timer(this, TIMER_ID) | |
{ | |
m_text = wxT("NOT FOUND"); | |
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); | |
m_timer.Start(150); | |
} | |
WXLRESULT MyFrame::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam) | |
{ | |
if (nMsg == WM_NCHITTEST) { | |
WXLRESULT result = wxFrame::MSWWindowProc(nMsg, wParam, lParam); | |
if (result == HTCLIENT) { | |
result = HTCAPTION; | |
} | |
return result; | |
} | |
return wxFrame::MSWWindowProc(nMsg, wParam, lParam); | |
} | |
static wxString GetWindowTitle(HWND hwnd) | |
{ | |
WCHAR wz[256] = { 0 }; | |
GetWindowTextW(hwnd, wz, 255); | |
wz[255] = 0; | |
wxString s(wz); | |
return s; | |
} | |
static wxString GetWindowClass(HWND hwnd) | |
{ | |
WCHAR wz[256] = { 0 }; | |
GetClassNameW(hwnd, wz, 255); | |
wz[255] = 0; | |
wxString s(wz); | |
return s; | |
} | |
wxString GetClickerState(wxString &title) | |
{ | |
wxRegEx re(wxT("^\\(([0-9]+|G)\\).+$")); | |
wxString text; | |
if (title.EndsWith(wxT(" - Cookie Clicker"))) { | |
if (re.Matches(title)) { | |
wxString m = re.GetMatch(title, 1); | |
if (m == wxT("G")) { | |
text = wxT("●●●"); | |
} else { | |
text = wxT("○ "); | |
text += m; | |
} | |
} | |
} | |
return text; | |
} | |
// event handlers | |
void MyFrame::OnPaint(wxPaintEvent& WXUNUSED(event)) | |
{ | |
wxPaintDC dc(this); | |
dc.SetFont(m_font); | |
wxSize sz = (dc.GetSize() - dc.GetTextExtent(m_text)) / 2; | |
dc.DrawText(m_text, sz.GetWidth(), sz.GetHeight()); | |
} | |
static BOOL CALLBACK EnumChildWindowsProc(HWND hwnd, LPARAM lParam) | |
{ | |
HWND &hChromeWnd = *reinterpret_cast<HWND *>(lParam); | |
wxString title = GetWindowTitle(hwnd); | |
bool ret = GetClickerState(title).IsEmpty(); | |
if (!ret) hChromeWnd = hwnd; | |
return ret; | |
} | |
static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) | |
{ | |
wxString clz = GetWindowClass(hwnd); | |
if (!clz.StartsWith(wxT("Chrome_WidgetWin"))) | |
return TRUE; | |
EnumChildWindows(hwnd, EnumChildWindowsProc, lParam); | |
HWND hChildWnd = *reinterpret_cast<HWND *>(lParam); | |
return hChildWnd == 0; | |
} | |
void MyFrame::OnTimer(wxTimerEvent& WXUNUSED(event)) | |
{ | |
wxString ns; | |
HWND hwnd = 0; | |
if (!m_chromeWindow || !IsWindow(m_chromeWindow)) { | |
EnumWindows(EnumWindowsProc, reinterpret_cast<LPARAM>(&hwnd)); | |
m_chromeWindow = hwnd; | |
} | |
if (m_chromeWindow) { | |
wxString title = GetWindowTitle(m_chromeWindow); | |
ns = GetClickerState(title); | |
if (ns.IsEmpty()) m_chromeWindow = 0; | |
} | |
if (!m_chromeWindow) { | |
ns = wxT("NOT FOUND"); | |
} | |
if (m_text != ns) { | |
m_text = ns; | |
Refresh(); | |
} | |
} | |
void MyFrame::OnChar(wxKeyEvent& event) | |
{ | |
if (event.GetKeyCode() == WXK_ESCAPE) { | |
Close(true); | |
return; | |
} | |
event.Skip(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment