![]() |
WGX library Architecture - Reference Manual - Guides |
|
00001 /* 00002 * WGX - Windows GUI Extended Library. 00003 * Copyright (c) 2007-2010 by Dmitri Arkhangelski (dmitriar@gmail.com). 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00018 */ 00019 00027 /* 00028 * An article of Mumtaz Zaheer from Pakistan helped me very much 00029 * to make a valid subclassing: 00030 * http://www.codeproject.com/KB/winsdk/safesubclassing.aspx 00031 */ 00032 00033 #define WIN32_NO_STATUS 00034 #include <windows.h> 00035 00036 #include "wgx.h" 00037 00038 #define WIN_ARRAY_SIZE 1024 00039 00040 typedef struct _CHILD_WINDOW { 00041 HWND hWindow; 00042 WNDPROC OldWindowProcedure; 00043 HACCEL hAccelerator; 00044 HWND hMainWindow; 00045 BOOL isWindowUnicode; 00046 } CHILD_WINDOW, *PCHILD_WINDOW; 00047 00048 CHILD_WINDOW win[WIN_ARRAY_SIZE]; 00049 int idx; 00050 BOOL first_call = TRUE; 00051 BOOL error_flag = FALSE; 00052 00053 LRESULT CALLBACK NewWndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) 00054 { 00055 int i, found = 0; 00056 MSG message; 00057 00058 /* search for our window in win array */ 00059 for(i = 0; i <= idx; i++){ 00060 if(win[i].hWindow == hWnd){ 00061 found = 1; break; 00062 } 00063 } 00064 00065 if(found){ 00066 if(iMsg == WM_KEYDOWN){ 00067 message.hwnd = hWnd; 00068 message.message = iMsg; 00069 message.wParam = wParam; 00070 message.lParam = lParam; 00071 message.pt.x = message.pt.y = 0; 00072 message.time = 0; 00073 /* TranslateAcceleratorW ? */ 00074 (void)TranslateAccelerator(win[i].hMainWindow,win[i].hAccelerator,&message); 00075 } 00076 if(win[i].isWindowUnicode) 00077 return CallWindowProcW(win[i].OldWindowProcedure,hWnd,iMsg,wParam,lParam); 00078 else 00079 return CallWindowProc(win[i].OldWindowProcedure,hWnd,iMsg,wParam,lParam); 00080 } 00081 /* very extraordinary situation */ 00082 if(!error_flag){ /* show message box once */ 00083 error_flag = TRUE; 00084 MessageBox(NULL,"OldWindowProcedure is lost!","Error!",MB_OK | MB_ICONHAND); 00085 } 00086 return 0; 00087 } 00088 00100 BOOL __stdcall WgxAddAccelerators(HINSTANCE hInstance,HWND hWindow,UINT AccelId) 00101 { 00102 HACCEL hAccel; 00103 HANDLE hChild; 00104 WNDPROC OldWndProc; 00105 BOOL isWindowUnicode; 00106 00107 /* Load the accelerator table. */ 00108 hAccel = LoadAccelerators(hInstance,MAKEINTRESOURCE(AccelId)); 00109 if(!hAccel) return FALSE; 00110 00111 if(first_call){ 00112 memset(win,0,sizeof(win)); 00113 idx = 0; 00114 first_call = FALSE; 00115 } 00116 00117 /* Set accelerator for the main window. */ 00118 /* FIXME: decide is it neccessary or not. */ 00119 00120 /* Set accelerator for children. */ 00121 hChild = GetWindow(hWindow,GW_CHILD); 00122 while(hChild){ 00123 if(idx >= (WIN_ARRAY_SIZE - 1)) 00124 return FALSE; /* too many child windows */ 00125 00126 if(IsWindowUnicode(hChild)) isWindowUnicode = TRUE; 00127 else isWindowUnicode = FALSE; 00128 00129 if(isWindowUnicode) 00130 OldWndProc = (WNDPROC)SetWindowLongPtrW(hChild,GWLP_WNDPROC,(LONG_PTR)NewWndProc); 00131 else 00132 OldWndProc = (WNDPROC)SetWindowLongPtr(hChild,GWLP_WNDPROC,(LONG_PTR)NewWndProc); 00133 00134 if(OldWndProc){ 00135 win[idx].hWindow = hChild; 00136 win[idx].OldWindowProcedure = OldWndProc; 00137 win[idx].hAccelerator = hAccel; 00138 win[idx].hMainWindow = hWindow; 00139 win[idx].isWindowUnicode = isWindowUnicode; 00140 idx ++; 00141 } 00142 hChild = GetWindow(hChild,GW_HWNDNEXT); 00143 } 00144 00145 return TRUE; 00146 } 00147